Skip to main content

Adding Due Collections to Cash Register

Learn how to add a comprehensive due collections display to your POS cash register that shows collected payments, pending dues, and overdue amounts.

๐Ÿ“‹ What You'll Buildโ€‹

Due Collections Preview

By the end of this tutorial, your cash register will display:

  • โœ… Collected Today: All due payments received today (business-wide)
  • โš ๏ธ Pending Due Today: Outstanding amounts from today's sales
  • ๐Ÿ”ด Overdue Amounts: Previous days' unpaid dues (shows when applicable)

๐ŸŽฏ Featuresโ€‹

  • Business-wide visibility (not just current cashier)
  • Real-time data with transaction counts
  • Smart conditional display (overdue box only shows when needed)
  • Beautiful responsive design with icons
  • Print-friendly styling
  • Works in both register details and close register modals

๐Ÿ“š Prerequisitesโ€‹

  • Laravel-based POS system
  • Basic knowledge of PHP and Blade templates
  • Access to controller files and views
  • Understanding of database relationships

๐Ÿš€ Implementation Stepsโ€‹

Step 1: Update the CashRegisterUtil Classโ€‹

First, we'll add the due collections logic to your app/Utils/CashRegisterUtil.php.

1.1 Add the Due Collections Methodโ€‹

Add this method to your app/Utils/CashRegisterUtil.php:

public function getTodayDueCollections($user_id, $open_time, $close_time)
{
$business_id = request()->session()->get('user.business_id');

// COLLECTED TODAY - Payments made today that reduce existing due amounts
// This includes: payments on old invoices + additional payments on today's invoices
$today_due = DB::table('transaction_payments as tp')
->join('transactions as t', 'tp.transaction_id', '=', 't.id')
->whereDate('tp.paid_on', now()->toDateString()) // Payments made today
->where('t.type', 'sell')
->where('t.status', 'final')
->where('t.business_id', $business_id)
// Exclude initial payments made at the time of sale creation
->where(function($query) {
$query->whereRaw('DATE(tp.paid_on) != DATE(t.created_at)') // Payment made on different day than sale
->orWhereRaw('tp.created_at > DATE_ADD(t.created_at, INTERVAL 5 MINUTE)'); // Or payment made more than 5 minutes after sale creation
})
->select(
DB::raw('SUM(tp.amount) as total_due_collected'),
DB::raw('COUNT(DISTINCT tp.transaction_id) as total_due_transactions')
)
->first();

// PENDING DUES TODAY - Transactions created today that still have pending amounts
$pending_dues = DB::table('transactions as t')
->whereDate('t.transaction_date', now()->toDateString()) // Transactions created today
->where('t.type', 'sell')
->where('t.status', 'final')
->where('t.business_id', $business_id)
->where('t.payment_status', '!=', 'paid') // Not fully paid
->select(
DB::raw('SUM(t.final_total - COALESCE(
(SELECT SUM(amount) FROM transaction_payments WHERE transaction_id = t.id), 0
)) as total_pending_due'),
DB::raw('COUNT(t.id) as total_pending_transactions')
)
->first();

// OVERDUE AMOUNTS - Previous days' unpaid transactions
$overdue_amounts = DB::table('transactions as t')
->whereDate('t.transaction_date', '<', now()->toDateString()) // Previous days
->where('t.type', 'sell')
->where('t.status', 'final')
->where('t.business_id', $business_id)
->where('t.payment_status', '!=', 'paid') // Not fully paid
->select(
DB::raw('SUM(t.final_total - COALESCE(
(SELECT SUM(amount) FROM transaction_payments WHERE transaction_id = t.id), 0
)) as total_overdue'),
DB::raw('COUNT(t.id) as total_overdue_transactions')
)
->first();

return [
'due_collected_today' => $today_due->total_due_collected ?? 0,
'due_transactions_count' => $today_due->total_due_transactions ?? 0,
'pending_due_today' => $pending_dues->total_pending_due ?? 0,
'pending_transactions_count' => $pending_dues->total_pending_transactions ?? 0,
'overdue_amount' => $overdue_amounts->total_overdue ?? 0,
'overdue_transactions_count' => $overdue_amounts->total_overdue_transactions ?? 0,
];
}
public function getTodayDueCashCollections($register_id, $open_time, $close_time)
{
$business_id = request()->session()->get('user.business_id');

// Get cash payments made today for due collections
$due_cash_collections = DB::table('transaction_payments as tp')
->join('transactions as t', 'tp.transaction_id', '=', 't.id')
->whereDate('tp.paid_on', now()->toDateString()) // Payments made today
->where('t.business_id', $business_id)
->where('t.type', 'sell')
->where('t.status', 'final')
->where('tp.method', 'cash') // Only cash payments
// Exclude initial payments made at time of sale creation
->where(function ($query) {
$query->whereRaw('DATE(tp.paid_on) != DATE(t.created_at)') // Different day
->orWhereRaw('tp.created_at > DATE_ADD(t.created_at, INTERVAL 5 MINUTE)'); // Or 5+ minutes later
})
->sum('tp.amount');

return $due_cash_collections ?? 0;
}

Step 2: Update the Controllerโ€‹

Now update your app/Http/Controllers/CashRegisterController.php to call the utility method.

2.1 Update getRegisterDetails Methodโ€‹

Update your existing getRegisterDetails() method in the controller:

public function getRegisterDetails()
{
if (!auth()->user()->can('view_cash_register')) {
abort(403, 'Unauthorized action.');
}

$business_id = request()->session()->get('user.business_id');

$register_details = $this->cashRegisterUtil->getRegisterDetails();

$user_id = auth()->user()->id;
$open_time = $register_details['open_time'];
$close_time = \Carbon::now()->toDateTimeString();

$is_types_of_service_enabled = $this->moduleUtil->isModuleEnabled('types_of_service');

$details = $this->cashRegisterUtil->getRegisterTransactionDetails($user_id, $open_time, $close_time, $is_types_of_service_enabled);

// Add due collections data
$due_collections = $this->cashRegisterUtil->getTodayDueCollections($user_id, $open_time, $close_time);
$details['due_collections'] = $due_collections;

$payment_types = $this->cashRegisterUtil->payment_types($register_details->location_id, true, $business_id);

return view('cash_register.register_details')
->with(compact('register_details', 'details', 'payment_types', 'close_time'));
}

2.2 Update your existing getRegisterDetails method in CashRegisterUtil.phpโ€‹

public function getRegisterDetails($register_id = null)
{
$query = CashRegister::leftjoin(
'cash_register_transactions as ct',
'ct.cash_register_id',
'=',
'cash_registers.id'
)
->join(
'users as u',
'u.id',
'=',
'cash_registers.user_id'
)
->leftJoin(
'business_locations as bl',
'bl.id',
'=',
'cash_registers.location_id'
);

if (empty($register_id)) {
$user_id = auth()->user()->id;
$query->where('user_id', $user_id)
->where('cash_registers.status', 'open');
} else {
$query->where('cash_registers.id', $register_id);
}

$register_details = $query->select(
'cash_registers.id as register_id',
'cash_registers.created_at as open_time',
'cash_registers.closed_at as closed_at',
'cash_registers.user_id',
'cash_registers.closing_note',
'cash_registers.location_id',
'cash_registers.denominations',
DB::raw("SUM(IF(transaction_type='initial', amount, 0)) as cash_in_hand"),
DB::raw("SUM(IF(transaction_type='sell', amount, IF(transaction_type='refund', -1 * amount, 0))) as total_sale"),
DB::raw("SUM(IF(transaction_type='expense', IF(transaction_type='refund', -1 * amount, amount), 0)) as total_expense"),
DB::raw("SUM(IF(pay_method='cash', IF(transaction_type='sell', amount, 0), 0)) as total_cash"),
DB::raw("SUM(IF(pay_method='cash', IF(transaction_type='expense', amount, 0), 0)) as total_cash_expense"),
DB::raw("SUM(IF(pay_method='cheque', IF(transaction_type='sell', amount, 0), 0)) as total_cheque"),
DB::raw("SUM(IF(pay_method='cheque', IF(transaction_type='expense', amount, 0), 0)) as total_cheque_expense"),
DB::raw("SUM(IF(pay_method='card', IF(transaction_type='sell', amount, 0), 0)) as total_card"),
DB::raw("SUM(IF(pay_method='card', IF(transaction_type='expense', amount, 0), 0)) as total_card_expense"),
DB::raw("SUM(IF(pay_method='bank_transfer', IF(transaction_type='sell', amount, 0), 0)) as total_bank_transfer"),
DB::raw("SUM(IF(pay_method='bank_transfer', IF(transaction_type='expense', amount, 0), 0)) as total_bank_transfer_expense"),
DB::raw("SUM(IF(pay_method='other', IF(transaction_type='sell', amount, 0), 0)) as total_other"),
DB::raw("SUM(IF(pay_method='other', IF(transaction_type='expense', amount, 0), 0)) as total_other_expense"),
DB::raw("SUM(IF(pay_method='advance', IF(transaction_type='sell', amount, 0), 0)) as total_advance"),
DB::raw("SUM(IF(pay_method='advance', IF(transaction_type='expense', amount, 0), 0)) as total_advance_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_1', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_1"),
DB::raw("SUM(IF(pay_method='custom_pay_2', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_2"),
DB::raw("SUM(IF(pay_method='custom_pay_3', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_3"),
DB::raw("SUM(IF(pay_method='custom_pay_4', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_4"),
DB::raw("SUM(IF(pay_method='custom_pay_5', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_5"),
DB::raw("SUM(IF(pay_method='custom_pay_6', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_6"),
DB::raw("SUM(IF(pay_method='custom_pay_7', IF(transaction_type='sell', amount, 0), 0)) as total_custom_pay_7"),
DB::raw("SUM(IF(pay_method='custom_pay_1', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_1_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_2', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_2_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_3', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_3_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_4', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_4_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_5', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_5_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_6', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_6_expense"),
DB::raw("SUM(IF(pay_method='custom_pay_7', IF(transaction_type='expense', amount, 0), 0)) as total_custom_pay_7_expense"),
DB::raw("SUM(IF(transaction_type='refund', amount, 0)) as total_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='cash', amount, 0), 0)) as total_cash_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='cheque', amount, 0), 0)) as total_cheque_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='card', amount, 0), 0)) as total_card_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='bank_transfer', amount, 0), 0)) as total_bank_transfer_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='other', amount, 0), 0)) as total_other_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='advance', amount, 0), 0)) as total_advance_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_1', amount, 0), 0)) as total_custom_pay_1_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_2', amount, 0), 0)) as total_custom_pay_2_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_3', amount, 0), 0)) as total_custom_pay_3_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_4', amount, 0), 0)) as total_custom_pay_4_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_5', amount, 0), 0)) as total_custom_pay_5_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_6', amount, 0), 0)) as total_custom_pay_6_refund"),
DB::raw("SUM(IF(transaction_type='refund', IF(pay_method='custom_pay_7', amount, 0), 0)) as total_custom_pay_7_refund"),
DB::raw("SUM(IF(pay_method='cheque', 1, 0)) as total_cheques"),
DB::raw("SUM(IF(pay_method='card', 1, 0)) as total_card_slips"),
DB::raw("CONCAT(COALESCE(surname, ''), ' ', COALESCE(first_name, ''), ' ', COALESCE(last_name, '')) as user_name"),
'u.email',
'bl.name as location_name'
)->first();

// ADD DUE COLLECTION CASH TO TOTAL CASH
if ($register_details) {
$open_time = $register_details->open_time;
$close_time = \Carbon::now()->toDateTimeString();

// Get due collection cash payments
$due_cash_collections = $this->getTodayDueCashCollections($register_details->register_id, $open_time, $close_time);

// Add due collections to total cash
$register_details->total_cash = ($register_details->total_cash ?? 0) + $due_cash_collections;
$register_details->due_cash_collections = $due_cash_collections; // For reference
}

return $register_details;
}

2.3 Update getCloseRegister Method (Optional)โ€‹

If you want the same feature in your close register modal, update your getCloseRegister() method: Now update your app/Http/Controllers/CashRegisterController.php to call the utility method.

public function getCloseRegister($id = null)
{
if (! auth()->user()->can('close_cash_register')) {
abort(403, 'Unauthorized action.');
}

$business_id = request()->session()->get('user.business_id');
$register_details = $this->cashRegisterUtil->getRegisterDetails($id);

$user_id = $register_details->user_id;
$open_time = $register_details['open_time'];
$close_time = \Carbon::now()->toDateTimeString();

$is_types_of_service_enabled = $this->moduleUtil->isModuleEnabled('types_of_service');

$details = $this->cashRegisterUtil->getRegisterTransactionDetails($user_id, $open_time, $close_time, $is_types_of_service_enabled);

// Add due collections data for close register modal too
$due_collections = $this->cashRegisterUtil->getTodayDueCollections($user_id, $open_time, $close_time);
$details['due_collections'] = $due_collections;

$payment_types = $this->cashRegisterUtil->payment_types($register_details->location_id, true, $business_id);

$pos_settings = ! empty(request()->session()->get('business.pos_settings')) ? json_decode(request()->session()->get('business.pos_settings'), true) : [];

return view('cash_register.close_register_modal')
->with(compact('register_details', 'details', 'payment_types', 'pos_settings'));
}

Step 2: Update the Register Details Viewโ€‹

Update your resources/views/cash_register/register_details.blade.php file.

2.1 Add Due Collections Sectionโ€‹

<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header mini_print">
<button type="button" class="close no-print" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h3 class="modal-title">@lang( 'cash_register.register_details' ) ( {{ \Carbon::createFromFormat('Y-m-d H:i:s',
$register_details->open_time)->format('jS M, Y h:i A') }} - {{\Carbon::createFromFormat('Y-m-d H:i:s',
$close_time)->format('jS M, Y h:i A')}} )</h3>
</div>

<div class="modal-body">
@include('cash_register.payment_details')

<!-- Add Due Collections Section -->
@if(isset($details['due_collections']))
<hr class="no-print">
<div class="row no-print">
<div class="col-md-12">
<h4><i class="fa fa-clock-o"></i> @lang('lang_v1.due_collections_today')</h4>
<div class="row">
<div class="col-md-4">
<div class="info-box bg-green due-collection-box">
<span class="info-box-icon due-collection-icon">
<i class="fa fa-check-circle"></i>
</span>
<div class="info-box-content">
<span class="info-box-text due-collection-title">@lang('lang_v1.collected_today')</span>
<span class="info-box-number due-collection-amount">
@format_currency($details['due_collections']['due_collected_today'])
</span>
<span class="progress-description due-collection-desc">
{{ $details['due_collections']['due_transactions_count'] }} @lang('lang_v1.transactions')
</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="info-box bg-yellow due-collection-box">
<span class="info-box-icon due-collection-icon">
<i class="fa fa-exclamation-triangle"></i>
</span>
<div class="info-box-content">
<span class="info-box-text due-collection-title">@lang('lang_v1.pending_due_today')</span>
<span class="info-box-number due-collection-amount">
@format_currency($details['due_collections']['pending_due_today'])
</span>
<span class="progress-description due-collection-desc">
{{ $details['due_collections']['pending_transactions_count'] }} @lang('lang_v1.transactions')
</span>
</div>
</div>
</div>
@if($details['due_collections']['overdue_amount'] > 0)
<div class="col-md-4">
<div class="info-box bg-red due-collection-box">
<span class="info-box-icon due-collection-icon">
<i class="fa fa-exclamation-circle"></i>
</span>
<div class="info-box-content">
<span class="info-box-text due-collection-title">@lang('lang_v1.overdue_amounts')</span>
<span class="info-box-number due-collection-amount">
@format_currency($details['due_collections']['overdue_amount'])
</span>
<span class="progress-description due-collection-desc">
{{ $details['due_collections']['overdue_transactions_count'] }} @lang('lang_v1.transactions')
</span>
</div>
</div>
</div>
@endif
</div>
</div>
</div>
@endif

<hr>
@if(!empty($register_details->denominations))
@php
$total = 0;
@endphp
<div class="row">
<div class="col-md-8 col-sm-12">
<h3>@lang( 'lang_v1.cash_denominations' )</h3>
<table class="table table-slim">
<thead>
<tr>
<th width="20%" class="text-right">@lang('lang_v1.denomination')</th>
<th width="20%">&nbsp;</th>
<th width="20%" class="text-center">@lang('lang_v1.count')</th>
<th width="20%">&nbsp;</th>
<th width="20%" class="text-left">@lang('sale.subtotal')</th>
</tr>
</thead>
<tbody>
@foreach($register_details->denominations as $key => $value)
<tr>
<td class="text-right">{{$key}}</td>
<td class="text-center">X</td>
<td class="text-center">{{$value ?? 0}}</td>
<td class="text-center">=</td>
<td class="text-left">
@format_currency($key * $value)
</td>
</tr>
@php
$total += ($key * $value);
@endphp
@endforeach
</tbody>
<tfoot>
<tr>
<th colspan="4" class="text-center">@lang('sale.total')</th>
<td>@format_currency($total)</td>
</tr>
</tfoot>
</table>
</div>
</div>
@endif

<div class="row">
<div class="col-xs-6">
<b>@lang('report.user'):</b> {{ $register_details->user_name}}<br>
<b>@lang('business.email'):</b> {{ $register_details->email}}<br>
<b>@lang('business.business_location'):</b> {{ $register_details->location_name}}<br>
</div>
@if(!empty($register_details->closing_note))
<div class="col-xs-6">
<strong>@lang('cash_register.closing_note'):</strong><br>
{{$register_details->closing_note}}
</div>
@endif
</div>
</div>

<div class="modal-footer">
<button type="button" class="tw-dw-btn tw-dw-btn-primary tw-text-white no-print print-mini-button"
aria-label="Print">
<i class="fa fa-print"></i> @lang('messages.print_mini')
</button>
<button type="button" class="tw-dw-btn tw-dw-btn-primary tw-text-white no-print" aria-label="Print"
onclick="$(this).closest('div.modal').printThis();">
<i class="fa fa-print"></i> @lang( 'messages.print_detailed' )
</button>

<button type="button" class="tw-dw-btn tw-dw-btn-neutral tw-text-white no-print" data-dismiss="modal">@lang(
'messages.cancel' )
</button>
</div>

</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

<style type="text/css">
@media print {
.modal {
position: absolute;
left: 0;
top: 0;
margin: 0;
padding: 0;
overflow: visible !important;
}

.info-box {
border: 1px solid #ddd;
margin-bottom: 10px;
padding: 10px;
}

.info-box-icon {
display: none;
}
}

/* Due Collection Styling */
.due-collection-box {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
position: relative;
}

.due-collection-icon {
background: rgba(255, 255, 255, 0.2) !important;
color: white !important;
display: block !important;
width: 70px !important;
height: 70px !important;
line-height: 70px !important;
text-align: center !important;
float: left !important;
font-size: 30px !important;
border-radius: 0 !important;
}

.due-collection-icon i {
color: white !important;
font-size: 30px !important;
display: inline-block !important;
vertical-align: middle !important;
line-height: normal !important;
}

.due-collection-title {
color: white !important;
font-weight: bold;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 0.5px;
}

.due-collection-amount {
color: white !important;
font-weight: bold;
font-size: 24px;
}

.due-collection-desc {
color: rgba(255, 255, 255, 0.9) !important;
font-size: 12px;
}

/* Ensure proper spacing and layout */
.due-collection-box .info-box-content {
margin-left: 85px;
padding: 15px 10px;
}
</style>

<script>
$(document).ready(function () {
$(document).on('click', '.print-mini-button', function () {
$('.mini_print').printThis();
});
});
</script>

2.2 Add CSS Stylingโ€‹

Add this CSS to your view file (before the closing </div> tags):

<style type="text/css">
@media print {
.modal {
position: absolute;
left: 0;
top: 0;
margin: 0;
padding: 0;
overflow: visible!important;
}
.info-box {
border: 1px solid #ddd;
margin-bottom: 10px;
padding: 10px;
}
.info-box-icon {
display: none;
}
}

/* Due Collection Styling */
.due-collection-box {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
overflow: hidden;
position: relative;
}

.due-collection-icon {
background: rgba(255,255,255,0.2) !important;
color: white !important;
display: block !important;
width: 70px !important;
height: 70px !important;
line-height: 70px !important;
text-align: center !important;
float: left !important;
font-size: 30px !important;
border-radius: 0 !important;
}

.due-collection-icon i {
color: white !important;
font-size: 30px !important;
display: inline-block !important;
vertical-align: middle !important;
line-height: normal !important;
}

.due-collection-title {
color: white !important;
font-weight: bold;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 0.5px;
}

.due-collection-amount {
color: white !important;
font-weight: bold;
font-size: 24px;
}

.due-collection-desc {
color: rgba(255,255,255,0.9) !important;
font-size: 12px;
}

.due-collection-box .info-box-content {
margin-left: 85px;
padding: 15px 10px;
}
</style>

Step 3: Add Language Entriesโ€‹

Add these entries to your resources/lang/en/lang_v1.php file:

return [
// ... existing entries ...

'due_collections_today' => 'Today\'s Due Collections',
'collected_today' => 'Collected Today',
'pending_due_today' => 'Pending Due Today',
'overdue_amounts' => 'Overdue Amounts',
'transactions' => 'Transactions',

// ... rest of your language entries ...
];

Step 4: Update Close Register Modal (Optional)โ€‹

If you want the same feature in your close register modal, update your resources/views/cash_register/close_register.blade.php with the same due collections section and CSS.

<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
{!! Form::open(['url' => action([\App\Http\Controllers\CashRegisterController::class, 'postCloseRegister']),
'method' => 'post' ]) !!}

{!! Form::hidden('user_id', $register_details->user_id); !!}
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
aria-hidden="true">&times;</span></button>
<h3 class="modal-title">@lang( 'cash_register.current_register' ) ( {{ \Carbon::createFromFormat('Y-m-d H:i:s',
$register_details->open_time)->format('jS M, Y h:i A') }} - {{ \Carbon::now()->format('jS M, Y h:i A') }})</h3>
</div>

<div class="modal-body">
@include('cash_register.payment_details')

<!-- Add Due Collections Section -->
@if(isset($details['due_collections']))
<hr class="no-print">
<div class="row no-print">
<div class="col-md-12">
<h4><i class="fa fa-clock-o"></i> @lang('lang_v1.due_collections_today')</h4>
<div class="row">
<div class="col-md-4">
<div class="info-box bg-green due-collection-box">
<span class="info-box-icon due-collection-icon">
<i class="fa fa-check-circle"></i>
</span>
<div class="info-box-content">
<span class="info-box-text due-collection-title">@lang('lang_v1.collected_today')</span>
<span class="info-box-number due-collection-amount">
@format_currency($details['due_collections']['due_collected_today'])
</span>
<span class="progress-description due-collection-desc">
{{ $details['due_collections']['due_transactions_count'] }} @lang('lang_v1.transactions')
</span>
</div>
</div>
</div>
<div class="col-md-4">
<div class="info-box bg-yellow due-collection-box">
<span class="info-box-icon due-collection-icon">
<i class="fa fa-exclamation-triangle"></i>
</span>
<div class="info-box-content">
<span class="info-box-text due-collection-title">@lang('lang_v1.pending_due_today')</span>
<span class="info-box-number due-collection-amount">
@format_currency($details['due_collections']['pending_due_today'])
</span>
<span class="progress-description due-collection-desc">
{{ $details['due_collections']['pending_transactions_count'] }} @lang('lang_v1.transactions')
</span>
</div>
</div>
</div>
@if($details['due_collections']['overdue_amount'] > 0)
<div class="col-md-4">
<div class="info-box bg-red due-collection-box">
<span class="info-box-icon due-collection-icon">
<i class="fa fa-exclamation-circle"></i>
</span>
<div class="info-box-content">
<span class="info-box-text due-collection-title">@lang('lang_v1.overdue_amounts')</span>
<span class="info-box-number due-collection-amount">
@format_currency($details['due_collections']['overdue_amount'])
</span>
<span class="progress-description due-collection-desc">
{{ $details['due_collections']['overdue_transactions_count'] }} @lang('lang_v1.transactions')
</span>
</div>
</div>
</div>
@endif
</div>
</div>
</div>
@endif

<hr>
<div class="row">
<div class="col-sm-4">
<div class="form-group">
{!! Form::label('closing_amount', __( 'cash_register.total_cash' ) . ':*') !!}
{!! Form::text('closing_amount', @num_format($register_details->cash_in_hand + $register_details->total_cash
- $register_details->total_cash_refund - $register_details->total_cash_expense), ['class' => 'form-control
input_number', 'required', 'placeholder' => __( 'cash_register.total_cash' ) ]); !!}
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
{!! Form::label('total_card_slips', __( 'cash_register.total_card_slips' ) . ':*') !!}
@show_tooltip(__('tooltip.total_card_slips'))
{!! Form::number('total_card_slips', $register_details->total_card_slips, ['class' => 'form-control',
'required', 'placeholder' => __( 'cash_register.total_card_slips' ), 'min' => 0 ]); !!}
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
{!! Form::label('total_cheques', __( 'cash_register.total_cheques' ) . ':*') !!}
@show_tooltip(__('tooltip.total_cheques'))
{!! Form::number('total_cheques', $register_details->total_cheques, ['class' => 'form-control', 'required',
'placeholder' => __( 'cash_register.total_cheques' ), 'min' => 0 ]); !!}
</div>
</div>
<hr>
<div class="col-md-8 col-sm-12">
<h3>@lang( 'lang_v1.cash_denominations' )</h3>
@if(!empty($pos_settings['cash_denominations']))
<table class="table table-slim">
<thead>
<tr>
<th width="20%" class="text-right">@lang('lang_v1.denomination')</th>
<th width="20%">&nbsp;</th>
<th width="20%" class="text-center">@lang('lang_v1.count')</th>
<th width="20%">&nbsp;</th>
<th width="20%" class="text-left">@lang('sale.subtotal')</th>
</tr>
</thead>
<tbody>
@foreach(explode(',', $pos_settings['cash_denominations']) as $dnm)
<tr>
<td class="text-right">{{$dnm}}</td>
<td class="text-center">X</td>
<td>{!! Form::number("denominations[$dnm]", null, ['class' => 'form-control cash_denomination input-sm',
'min' => 0, 'data-denomination' => $dnm, 'style' => 'width: 100px; margin:auto;' ]); !!}</td>
<td class="text-center">=</td>
<td class="text-left">
<span class="denomination_subtotal">0</span>
</td>
</tr>
@endforeach
</tbody>
<tfoot>
<tr>
<th colspan="4" class="text-center">@lang('sale.total')</th>
<td><span class="denomination_total">0</span></td>
</tr>
</tfoot>
</table>
@else
<p class="help-block">@lang('lang_v1.denomination_add_help_text')</p>
@endif
</div>
<hr>
<div class="col-sm-12">
<div class="form-group">
{!! Form::label('closing_note', __( 'cash_register.closing_note' ) . ':') !!}
{!! Form::textarea('closing_note', null, ['class' => 'form-control', 'placeholder' => __(
'cash_register.closing_note' ), 'rows' => 3 ]); !!}
</div>
</div>
</div>

<div class="row">
<div class="col-xs-6">
<b>@lang('report.user'):</b> {{ $register_details->user_name}}<br>
<b>@lang('business.email'):</b> {{ $register_details->email}}<br>
<b>@lang('business.business_location'):</b> {{ $register_details->location_name}}<br>
</div>
@if(!empty($register_details->closing_note))
<div class="col-xs-6">
<strong>@lang('cash_register.closing_note'):</strong><br>
{{$register_details->closing_note}}
</div>
@endif
</div>
</div>
<div class="modal-footer">
<button type="button" class="tw-dw-btn tw-dw-btn-neutral tw-text-white" data-dismiss="modal">@lang(
'messages.cancel' )</button>
<button type="submit" class="tw-dw-btn tw-dw-btn-primary tw-text-white">@lang( 'cash_register.close_register'
)</button>
</div>
{!! Form::close() !!}
</div><!-- /.modal-content -->
</div><!-- /.modal-dialog -->

<style type="text/css">
@media print {
.modal {
position: absolute;
left: 0;
top: 0;
margin: 0;
padding: 0;
overflow: visible !important;
}

.info-box {
border: 1px solid #ddd;
margin-bottom: 10px;
padding: 10px;
}

.info-box-icon {
display: none;
}
}

/* Due Collection Styling for Close Register Modal */
.due-collection-box {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
overflow: hidden;
position: relative;
}

.due-collection-icon {
background: rgba(255, 255, 255, 0.2) !important;
color: white !important;
display: block !important;
width: 70px !important;
height: 70px !important;
line-height: 70px !important;
text-align: center !important;
float: left !important;
font-size: 30px !important;
border-radius: 0 !important;
}

.due-collection-icon i {
color: white !important;
font-size: 30px !important;
display: inline-block !important;
vertical-align: middle !important;
line-height: normal !important;
}

.due-collection-title {
color: white !important;
font-weight: bold;
font-size: 14px;
text-transform: uppercase;
letter-spacing: 0.5px;
}

.due-collection-amount {
color: white !important;
font-weight: bold;
font-size: 24px;
}

.due-collection-desc {
color: rgba(255, 255, 255, 0.9) !important;
font-size: 12px;
}

/* Ensure proper spacing and layout */
.due-collection-box .info-box-content {
margin-left: 85px;
padding: 15px 10px;
}
</style>

๐Ÿงช Testingโ€‹

Test Scenariosโ€‹

  1. Create a credit sale: Make a sale with partial payment
  2. Collect due payment: Pay the remaining amount today
  3. Check register details: Verify "Collected Today" shows the payment
  4. Create overdue transactions: Make sales from previous days with unpaid amounts
  5. Verify overdue display: Check that red overdue box appears when applicable

Expected Resultsโ€‹

  • โœ… Collected Today: Shows all due payments received today
  • โœ… Pending Due Today: Shows unpaid amounts from today's sales
  • โœ… Overdue Amounts: Shows only when there are actually overdue transactions
  • โœ… Transaction Counts: Accurate count of affected transactions
  • โœ… Responsive Design: Works on mobile and desktop
  • โœ… Print Friendly: Looks good when printed

๐ŸŽจ Customizationโ€‹

Changing Colorsโ€‹

You can customize the box colors by modifying the Bootstrap classes:

<!-- Green for collected -->
<div class="info-box bg-green due-collection-box">

<!-- Yellow/Orange for pending -->
<div class="info-box bg-yellow due-collection-box">

<!-- Red for overdue -->
<div class="info-box bg-red due-collection-box">

Adding More Iconsโ€‹

Replace the Font Awesome icons with your preferred ones:

<!-- Available alternatives -->
<i class="fa fa-money"></i> <!-- Money icon -->
<i class="fa fa-clock-o"></i> <!-- Clock icon -->
<i class="fa fa-warning"></i> <!-- Warning icon -->
<i class="fa fa-calendar"></i> <!-- Calendar icon -->

Modifying Layoutโ€‹

Change from 3 boxes to 2 boxes by removing the overdue section or adjust column sizes:

<!-- For 2 equal boxes -->
<div class="col-md-6">

<!-- For 3 equal boxes -->
<div class="col-md-4">

๐Ÿ”ง Troubleshootingโ€‹

Common Issuesโ€‹

Issue: Icons not showing

  • Solution: Ensure Font Awesome is loaded in your layout
  • Alternative: Use text symbols or different icon libraries

Issue: Data not appearing

  • Solution: Check that $details['due_collections'] is being passed to the view
  • Debug: Add {{ dd($details) }} to see what data is available

Issue: Incorrect amounts

  • Solution: Verify your database relationships match the query structure
  • Check: Ensure business_id is correctly set in session

Issue: Styling conflicts

  • Solution: Use more specific CSS selectors or !important declarations
  • Alternative: Move CSS to a separate file

Database Requirementsโ€‹

Ensure your database has these tables and relationships:

  • transactions table with business_id, payment_status, type, status columns
  • transaction_payments table with transaction_id, amount, paid_on columns
  • Proper foreign key relationships between tables

๐Ÿ“ Summaryโ€‹

You've successfully implemented a comprehensive due collections display that provides:

  • Real-time visibility into payment collections
  • Business-wide data for better decision making
  • Professional UI with responsive design
  • Smart conditional display for optimal user experience

This feature will help your business track due collections more effectively and improve cash flow management.