Client Overview
Invoice vs Payment Analysis
Payment Distribution
Payment Summary
Total Invoice Amount:
BDT {{ number_format($statementData['total_invoice_amount'] ?? 0, 2) }}
Total Paid Amount:
BDT {{ number_format($statementData['total_paid_amount'] ?? 0, 2) }}
Due Amount:
BDT {{ number_format(max(0, ($statementData['total_invoice_amount'] ?? 0) - ($statementData['total_paid_amount'] ?? 0)), 2) }}
Advance Amount:
BDT {{ number_format($statementData['advance_amount'] ?? 0, 2) }}
Payment Ratio:
{{ $statementData['total_invoice_amount'] > 0 ? round((($statementData['total_paid_amount'] ?? 0) / $statementData['total_invoice_amount']) * 100, 2) : 0 }}%
Due Ratio:
{{ $statementData['total_invoice_amount'] > 0 ? round((max(0, $statementData['total_invoice_amount'] - ($statementData['total_paid_amount'] ?? 0)) / $statementData['total_invoice_amount']) * 100, 2) : 0 }}%
Financial Summary
Total Invoices
{{ $statementData['total_invoices'] ?? 0 }}
Total Invoices Amount
BDT {{ number_format($statementData['total_invoice_amount'] ?? 0, 2) }}
Total Paid
BDT {{ number_format($statementData['total_paid_amount'] ?? 0, 2) }}
Due Amount
BDT {{ number_format(max(0, ($statementData['total_invoice_amount'] ?? 0) - ($statementData['total_paid_amount'] ?? 0)), 2) }}
Payment Schedules
Total Schedules
{{ $totalCount }}
Total Expected Amount
BDT {{ number_format($totalExpectedAmount, 2) }}
Total Payment Received
BDT {{ number_format($totalPaymentAmount, 2) }}
| # |
Invoice |
Expected Payment Date |
Expected Amount |
Payment Amount |
Status |
Remarks |
Reasons |
Actions |
@forelse($paymentSchedules as $index => $schedule)
| {{ $index + 1 }} |
{{ optional($schedule->salesInvoice)->invoice_no ?? 'N/A' }}
|
@if($schedule->expected_payment_date)
{{ $schedule->expected_payment_date->format('Y-m-d') }}
@php
$today = now()->startOfDay();
$expectedDate = $schedule->expected_payment_date->startOfDay();
$daysOverdue = $today->diffInDays($expectedDate);
@endphp
@if($expectedDate < $today && !$schedule->paid_on)
({{ $daysOverdue }} days overdue)
@endif
@else
N/A
@endif
|
BDT {{ number_format($schedule->expected_payment_amount, 2) }} |
BDT {{ number_format($schedule->transaction_payment_amount ?? 0, 2) }} |
@if($schedule->paid_on)
Paid
@elseif($schedule->expected_payment_date && $schedule->expected_payment_date->startOfDay() < now()->startOfDay())
Overdue
@else
Pending
@endif
|
{{ $schedule->remarks ?? '—' }} |
@if($schedule->scheduleBreakReason)
{{ $schedule->scheduleBreakReason->reason }}
@if($schedule->scheduleBreakReason->description)
{{ Str::limit($schedule->scheduleBreakReason->description, 50) }}
@endif
@else
—
@endif
|
@php
$today = now()->startOfDay();
$expectedDate = $schedule->expected_payment_date ? $schedule->expected_payment_date->startOfDay() : null;
// Show icon when Expected Payment Date is today or has passed (expired)
$isExpired = $expectedDate && $expectedDate <= $today;
@endphp
@if($isExpired)
@endif
|
@empty
|
No payment schedules found.
|
@endforelse
@if($paymentSchedules->count() > 0)
| Total Summary: |
BDT {{ number_format($totalExpectedAmount, 2) }} |
BDT {{ number_format($totalPaymentAmount, 2) }} |
|
@endif
Reseller Service Information
Service Type:
Reseller Account
Account Status:
{{ $user->is_active ? 'Active' : 'Inactive' }}
Service Start Date:
{{ $user->created_at->format('d M Y') }}
Service Duration:
{{ $user->created_at->diffInDays(now()) }} days
Access Level:
{{ ucfirst($user->role) }}
Branch Assignment:
{{ $user->branch ? $user->branch->name : 'Not assigned' }}
Last Login:
{{ $user->last_login_at ? $user->last_login_at->format('d M Y h:i A') : 'Never' }}
Account ID:
{{ $user->id }}
Email:
{{ $user->email }}
Phone:
{{ $user->phone ?? 'Not provided' }}
Company:
{{ $user->company_name ?? 'Not provided' }}
Last Service Update:
{{ $user->updated_at->format('d M Y h:i A') }}
Account Management Information
Account Created On:
{{ $user->created_at->format('d M Y') }}
Profile Completion:
@php
$fields = ['name', 'email', 'phone', 'address', 'company_name'];
$completed = collect($fields)->filter(function($field) use ($user) {
return !empty($user->$field);
})->count();
$percentage = ($completed / count($fields)) * 100;
@endphp
{{ round($percentage) }}%
Account Age:
{{ $user->created_at->diffInDays(now()) }} days
Last Profile Update:
{{ $user->updated_at->format('d M Y') }}
Login Count:
{{ $user->last_login_at ? 'Active User' : 'Never Logged In' }}
Account Status:
{{ $user->is_active ? 'Enabled' : 'Disabled' }}
Address:
{{ $user->address ?? 'Not provided' }}
Network Information
Network Access:
Reseller Portal
Network Status:
Connected
Service Areas:
{{ $user->branch ? $user->branch->name : 'Not assigned' }}
Network Type:
Broadband Internet
Connection Type:
Fiber Optic
Last Network Activity:
{{ $user->last_login_at ? $user->last_login_at->format('d M Y h:i A') : 'No activity' }}
Network Coverage:
Full Coverage
Bandwidth Allocation:
Unlimited
Products Information
Available Products:
Bandwidth Services, Internet Packages
Product Categories:
Internet Services, Data Plans
Service Packages:
Reseller Packages, Business Plans
Product Status:
Active
Product Pricing:
Competitive Rates
Product Support:
24/7 Technical Support
Product Updates:
Regular Updates
Product Documentation:
Available
Complaint Summary
Total Complaints:
0
Resolved Complaints:
0
Pending Complaints:
0
Last Complaint:
Never
Complaint Status:
Clean Record
Average Resolution Time:
N/A
Complaint Details
No complaints found
This reseller has no complaint history.
Complaint Categories:
None
Priority Level:
N/A
Complaint Source:
N/A
Message Summary
Total Messages:
0
Unread Messages:
0
Sent Messages:
0
Received Messages:
0
Last Message:
Never
Message Status:
All Clear
Message Details
No messages found
This reseller has no message history.
Message Types:
None
Message Priority:
N/A
Message Channels:
N/A
Personal Details
Full Name:
{{ $user->name }}
Phone Number:
{{ $user->phone ?? 'Not provided' }}
Address:
{{ $user->address ?? 'Not provided' }}
Profile Photo:
@if($user->profile_photo)
@else
No photo uploaded
@endif
Company Details
Company Name:
{{ $user->company_name ?? 'Not provided' }}
Business Address:
{{ $user->address ?? 'Not provided' }}
Contact Person:
{{ $user->name }}
Contact Phone:
{{ $user->phone ?? 'Not provided' }}
Account Details
User ID:
{{ $user->id }}
Role:
{{ ucfirst($user->role) }}
Account Status:
{{ $user->is_active ? 'Active' : 'Inactive' }}
Branch Assignment:
{{ $user->branch ? $user->branch->name : 'Not assigned' }}
Account Created:
{{ $user->created_at->format('d M Y H:i') }}
Last Updated:
{{ $user->updated_at->format('d M Y H:i') }}
Last Login:
{{ $user->last_login_at ? $user->last_login_at->format('d M Y H:i') : 'Never' }}
@if($salesInvoices->count() > 0 || $bills->count() > 0)
| Inv. Number |
Inv. Month |
VAT |
Total |
Paid Amount |
Due Amount |
Status |
Due Date |
Actions |
@foreach($salesInvoices as $invoice)
{{ $invoice->invoice_no ?? $invoice->invoice_number ?? 'N/A' }}
@if($invoice->reference_number)
Ref: {{ $invoice->reference_number }}
@endif
|
@if($invoice->invoice_month)
{{ \Carbon\Carbon::parse($invoice->invoice_month)->format('M Y') }}
@else
N/A
@endif
|
৳{{ number_format($invoice->total_vat ?? 0, 2) }} |
৳{{ number_format($invoice->invoice_amount ?? 0, 2) }} |
@if($invoice->payment_status === 'paid')
৳{{ number_format($invoice->invoice_amount ?? 0, 2) }}
@elseif($invoice->payment_status === 'partial')
@php
$paidAmount = ($invoice->invoice_amount ?? 0) - ($invoice->due_amount ?? 0);
@endphp
৳{{ number_format($paidAmount, 2) }}
@else
৳0.00
@endif
|
@if($invoice->payment_status === 'paid')
৳0.00
@else
৳{{ number_format($invoice->due_amount ?? 0, 2) }}
@endif
|
@if($invoice->payment_status === 'paid')
Paid
@elseif($invoice->payment_status === 'partial')
Partial
@elseif($invoice->payment_status === 'unpaid')
Unpaid
@else
{{ ucfirst($invoice->payment_status ?? 'Unknown') }}
@endif
|
@if($invoice->payment_due)
{{ \Carbon\Carbon::parse($invoice->payment_due)->format('d M Y') }}
@if(\Carbon\Carbon::parse($invoice->payment_due)->isPast() && $invoice->payment_status !== 'paid')
Overdue
@endif
@else
N/A
@endif
|
@if($invoice->payment_status !== 'paid')
@endif
|
@endforeach
@foreach($bills as $bill)
|
{{ $bill->bill_number ?? 'N/A' }}
|
{{ $bill->month_year ?? 'N/A' }} |
৳0.00 |
৳{{ number_format($bill->total_amount ?? 0, 2) }} |
@if($bill->status === 'paid')
৳{{ number_format($bill->total_amount ?? 0, 2) }}
@if($bill->paid_date)
{{ \Carbon\Carbon::parse($bill->paid_date)->format('d M Y') }}
@endif
@else
৳0.00
@endif
|
@if($bill->status === 'paid')
৳0.00
@else
৳{{ number_format($bill->total_amount ?? 0, 2) }}
@endif
|
@if($bill->status === 'paid')
Paid
@if($bill->paid_date)
{{ \Carbon\Carbon::parse($bill->paid_date)->format('d M Y') }}
@endif
@elseif($bill->status === 'pending')
Pending
@elseif($bill->status === 'overdue')
Overdue
@else
{{ ucfirst($bill->status ?? 'Unknown') }}
@endif
|
@if($bill->due_date)
{{ \Carbon\Carbon::parse($bill->due_date)->format('d M Y') }}
@if(\Carbon\Carbon::parse($bill->due_date)->isPast() && $bill->status !== 'paid')
Overdue
@endif
@else
N/A
@endif
|
|
@endforeach
@if($salesInvoices->hasPages() || $bills->hasPages())
Showing {{ ($salesInvoices->currentPage() - 1) * $salesInvoices->perPage() + 1 }} to
{{ min($salesInvoices->currentPage() * $salesInvoices->perPage(), $salesInvoices->total()) }}
of {{ $salesInvoices->total() }} invoices and bills
@endif
@if($salesInvoices->hasPages())
{{ $salesInvoices->links() }}
@endif
@else
No bills found
This user has no generated bills or invoices.
@endif
Payment History Summary
|
Total Payments |
Total Transactions |
Total Amount |
Last Payment |
| Total |
{{ $paymentTransactions->where('transaction_type', 'payment')->count() }} |
{{ $paymentTransactions->count() }} |
BDT {{ number_format($paymentTransactions->where('transaction_type', 'payment')->sum('amount'), 2) }} |
@if($paymentTransactions->where('transaction_type', 'payment')->first())
{{ $paymentTransactions->where('transaction_type', 'payment')->first()->transaction_date->format('M d, Y') }}
@else
Never
@endif
|
| This Month |
{{ $paymentTransactions->where('transaction_type', 'payment')->filter(function($item) { return $item->transaction_date->month == now()->month && $item->transaction_date->year == now()->year; })->count() }} |
{{ $paymentTransactions->filter(function($item) { return $item->transaction_date->month == now()->month && $item->transaction_date->year == now()->year; })->count() }} |
BDT {{ number_format($paymentTransactions->where('transaction_type', 'payment')->filter(function($item) { return $item->transaction_date->month == now()->month && $item->transaction_date->year == now()->year; })->sum('amount'), 2) }} |
@php
$thisMonthPayment = $paymentTransactions->where('transaction_type', 'payment')->filter(function($item) { return $item->transaction_date->month == now()->month && $item->transaction_date->year == now()->year; })->first();
@endphp
@if($thisMonthPayment)
{{ $thisMonthPayment->transaction_date->format('M d, Y') }}
@else
No payments this month
@endif
|
@if($paymentTransactions->count() > 0)
| # |
Invoice |
Payment Method |
Account Holder |
Account Name |
Bank Account |
Account Number |
Received By |
Received Amount |
Transaction Date |
@foreach($paymentTransactions as $index => $transaction)
| {{ $index + 1 }} |
@if($transaction->salesInvoice)
{{ $transaction->salesInvoice->invoice_no }}
@else
N/A
@endif
|
{{ $transaction->payment_method ?? 'N/A' }}
|
{{ optional($transaction->accountHolderInfo)->name ?? 'N/A' }}
|
{{ $transaction->bankAccountInfo->account_name ?? 'N/A' }}
|
{{ $transaction->bankAccountInfo->bank_name ?? ($transaction->bank_account ?? 'N/A') }}
|
@if($transaction->bankAccountInfo && $transaction->bankAccountInfo->account_number)
{{ $transaction->bankAccountInfo->account_number }}
@else
N/A
@endif
|
{{ $transaction->received_by ?? 'N/A' }}
|
BDT {{ number_format($transaction->amount, 2) }}
|
{{ $transaction->transaction_date->format('M d, Y') }} |
@endforeach
| Total Payments: |
BDT {{ number_format($paymentTransactions->where('transaction_type', 'payment')->sum('amount'), 2) }} |
|
{{ $paymentTransactions->links() }}
@endif
Monthly Transaction Summary
| Month |
Total Invoices |
Invoice Amount |
Total Payments |
Payment Amount |
Due Balance |
Over Payment |
Paid Ratio(%) |
Due Ratio(%) |
@php
// Group transactions by month
$monthlyData = [];
// Process invoices by month
foreach($salesInvoices as $invoice) {
$monthKey = $invoice->invoice_date->format('Y-m');
if (!isset($monthlyData[$monthKey])) {
$monthlyData[$monthKey] = [
'month' => $invoice->invoice_date->format('M Y'),
'invoices' => 0,
'invoice_amount' => 0,
'payments' => 0,
'payment_amount' => 0,
'balance' => 0,
'over_payment' => 0,
'ratio' => 0,
'due_ratio' => 0
];
}
$monthlyData[$monthKey]['invoices']++;
$monthlyData[$monthKey]['invoice_amount'] += $invoice->invoice_amount;
}
// Process payments by month
foreach($paymentTransactions as $transaction) {
if($transaction->transaction_type === 'payment') {
$monthKey = $transaction->transaction_date->format('Y-m');
if (!isset($monthlyData[$monthKey])) {
$monthKey = $transaction->transaction_date->format('Y-m');
$monthlyData[$monthKey] = [
'month' => $transaction->transaction_date->format('M Y'),
'invoices' => 0,
'invoice_amount' => 0,
'payments' => 0,
'payment_amount' => 0,
'balance' => 0,
'over_payment' => 0,
'ratio' => 0,
'due_ratio' => 0
];
}
$monthlyData[$monthKey]['payments']++;
$monthlyData[$monthKey]['payment_amount'] += $transaction->amount;
}
}
// Calculate balance, over payment, and ratio for each month
foreach($monthlyData as $key => $data) {
// Due Balance: Only show positive balance (amount still owed)
$monthlyData[$key]['balance'] = max(0, $data['invoice_amount'] - $data['payment_amount']);
// Over Payment: If payment amount exceeds invoice amount
$monthlyData[$key]['over_payment'] = max(0, $data['payment_amount'] - $data['invoice_amount']);
// Ratio: Payment percentage of invoice amount
if ($data['invoice_amount'] > 0) {
$monthlyData[$key]['ratio'] = round(($data['payment_amount'] / $data['invoice_amount']) * 100, 2);
} else {
$monthlyData[$key]['ratio'] = 0;
}
// Due Ratio: Calculate from Paid Ratio (100% - Paid Ratio%)
$monthlyData[$key]['due_ratio'] = round(100 - $monthlyData[$key]['ratio'], 2);
}
// Sort by month (newest first)
krsort($monthlyData);
@endphp
@foreach($monthlyData as $monthData)
| {{ $monthData['month'] }} |
{{ $monthData['invoices'] }} |
BDT {{ number_format($monthData['invoice_amount'], 2) }} |
{{ $monthData['payments'] }} |
BDT {{ number_format($monthData['payment_amount'], 2) }} |
BDT {{ number_format($monthData['balance'], 2) }}
|
BDT {{ number_format($monthData['over_payment'], 2) }}
|
{{ $monthData['ratio'] }}%
|
{{ $monthData['due_ratio'] }}%
|
@endforeach
@if(empty($monthlyData))
| No monthly transactions found |
@endif
Gross Ratio Analysis
| Month |
Invoice Amount |
Payment Amount |
Due Amount |
Paid Ratio(%) |
Due Ratio(%) |
Status |
@php
// Calculate overall Paid Ratio and Due Ratio
$totalInvoiceAmount = collect($monthlyData)->sum('invoice_amount');
$totalPaymentAmount = collect($monthlyData)->sum('payment_amount');
$totalDueAmount = max(0, $totalInvoiceAmount - $totalPaymentAmount); // Only show positive due amount
$overallPaidRatio = $totalInvoiceAmount > 0 ? round(($totalPaymentAmount / $totalInvoiceAmount) * 100, 2) : 0;
$overallDueRatio = $totalInvoiceAmount > 0 ? round(($totalDueAmount / $totalInvoiceAmount) * 100, 2) : 0;
// Determine overall status
$overallStatus = '';
if ($overallPaidRatio >= 100) {
$overallStatus = 'Very Good';
} elseif ($overallPaidRatio >= 98) {
$overallStatus = 'Good';
} elseif ($overallPaidRatio >= 96) {
$overallStatus = 'Average';
} elseif ($overallPaidRatio >= 94) {
$overallStatus = 'Poor';
} else {
$overallStatus = 'Very Poor';
}
@endphp
| Total |
BDT {{ number_format($totalInvoiceAmount, 2) }} |
BDT {{ number_format($totalPaymentAmount, 2) }} |
BDT {{ number_format($totalDueAmount, 2) }} |
{{ $overallPaidRatio }}%
|
{{ $overallDueRatio }}%
|
@if($overallStatus == 'Very Good')
{{ $overallStatus }}
@elseif($overallStatus == 'Good')
{{ $overallStatus }}
@elseif($overallStatus == 'Average')
{{ $overallStatus }}
@elseif($overallStatus == 'Poor')
{{ $overallStatus }}
@else
{{ $overallStatus }}
@endif
|
Loss & Profit Analysis
| Month |
Sales Revenue |
Paid Amount |
Sales Cost |
Gross Cost |
NTTN Cost |
Profit/Loss (BW & NTTN)
|
Profit/Loss (Without Gross) |
Gross Profit Margin (%) |
Status |
Action |
@php
// Group transactions by month for Loss & Profit
$lossProfitData = [];
// Process sales invoices by month (Revenue and Paid Amount)
foreach($salesInvoices as $invoice) {
$monthKey = $invoice->invoice_date->format('Y-m');
if (!isset($lossProfitData[$monthKey])) {
$lossProfitData[$monthKey] = [
'month' => $invoice->invoice_date->format('M Y'),
'sales_revenue' => 0,
'paid_amount' => 0,
'cost_of_goods' => 0,
'gross_profit' => 0,
'gross_profit_margin' => 0,
'profit_loss' => 0,
'profit_loss_nttn' => 0,
'profit_loss_without_gross' => 0,
'sales_cost' => 0,
'gross_cost' => 0,
'nttn_cost' => 0,
'sales_cost_plus_nttn_cost' => 0
];
}
$lossProfitData[$monthKey]['sales_revenue'] += $invoice->invoice_amount;
// Calculate paid amount for this invoice
$invoicePaidAmount = $invoice->transections()->where('transaction_type', 'payment')->sum('amount');
$lossProfitData[$monthKey]['paid_amount'] += $invoicePaidAmount;
}
// Process purchase invoices/bills by month (Cost of Goods Sold)
// Note: You may need to adjust this based on your purchase invoice structure
if (isset($bills) && $bills->count() > 0) {
foreach($bills as $bill) {
$billMonth = $bill->bill_date ? \Carbon\Carbon::parse($bill->bill_date)->format('Y-m') : null;
if ($billMonth) {
if (!isset($lossProfitData[$billMonth])) {
$lossProfitData[$billMonth] = [
'month' => \Carbon\Carbon::parse($bill->bill_date)->format('M Y'),
'sales_revenue' => 0,
'paid_amount' => 0,
'cost_of_goods' => 0,
'gross_profit' => 0,
'gross_profit_margin' => 0,
'profit_loss' => 0,
'profit_loss_nttn' => 0,
'profit_loss_without_gross' => 0,
'sales_cost' => 0,
'gross_cost' => 0,
'nttn_cost' => 0,
'sales_cost_plus_nttn_cost' => 0
];
}
$lossProfitData[$billMonth]['cost_of_goods'] += $bill->bill_amount ?? 0;
}
}
}
// Calculate Profit/Loss for each month (similar to loss-profit-details page)
// Only calculate for months where there is paid amount
foreach($lossProfitData as $key => $data) {
// Skip if no paid amount
if (($data['paid_amount'] ?? 0) <= 0) {
$lossProfitData[$key]['profit_loss'] = 0;
$lossProfitData[$key]['profit_loss_nttn'] = 0;
$lossProfitData[$key]['profit_loss_without_gross'] = 0;
$lossProfitData[$key]['sales_cost'] = 0;
$lossProfitData[$key]['gross_cost'] = 0;
$lossProfitData[$key]['nttn_cost'] = 0;
$lossProfitData[$key]['sales_cost_plus_nttn_cost'] = 0;
continue;
}
// Parse month
$monthDate = \Carbon\Carbon::createFromFormat('Y-m', $key);
$monthStart = $monthDate->copy()->startOfMonth();
$monthEnd = $monthDate->copy()->endOfMonth();
// Get sales invoices for this month with their paid amounts
$monthInvoices = \App\Models\SalesInvoice::with(['items.product', 'items.connectionType'])
->where('customer_id', $user->id)
->whereBetween('invoice_date', [$monthStart, $monthEnd])
->get();
// Calculate total paid amount for this month
$monthTotalPaid = $data['paid_amount'] ?? 0;
$monthTotalRevenue = $data['sales_revenue'] ?? 0;
// Calculate paid ratio (how much of the revenue is paid)
$paidRatio = $monthTotalRevenue > 0 ? ($monthTotalPaid / $monthTotalRevenue) : 0;
// Get NTTN costs for this month
$monthNttnCosts = \App\Models\NttnCost::with(['items.salesInvoiceItem'])
->where('user_id', $user->id)
->whereBetween('cost_date', [$monthStart, $monthEnd])
->where('status', 'active')
->get();
$totalNttnCost = $monthNttnCosts->sum('amount');
// Get user's sub_tag_id for commission calculation (like loss-profit-details)
$salesCommissionTag = \App\Models\Tag::where('name', 'Sales Comission')
->orWhere('name', 'Sales Commission')
->first();
$userSubTagId = null;
if ($salesCommissionTag) {
$userAssignment = \App\Models\UserTagAssignment::where('user_id', $user->id)
->where('tag_id', $salesCommissionTag->id)
->first();
$userSubTagId = $userAssignment ? $userAssignment->sub_tag_id : null;
}
// Create commission item prices map (like loss-profit-details)
$commissionItemPricesMap = [];
if ($userSubTagId) {
$monthStartForCommission = $monthStart->format('Y-m-01');
$commissionItemPrices = \DB::table('commission_item_prices')
->join('commission_items', 'commission_item_prices.commission_item_id', '=', 'commission_items.id')
->join('sales_invoice_items', function($join) {
$join->on('commission_items.bandwidth_item_id', '=', 'sales_invoice_items.product_id');
})
->join('sales_invoices', 'sales_invoice_items.sales_invoice_id', '=', 'sales_invoices.id')
->where('sales_invoices.customer_id', $user->id)
->whereBetween('sales_invoices.invoice_date', [$monthStart, $monthEnd])
->where('commission_items.sub_tag_id', $userSubTagId)
->whereDate('commission_item_prices.effective_month', $monthStartForCommission)
->where('commission_items.status', 'active')
->whereNotNull('sales_invoice_items.product_id')
->whereNotNull('commission_items.bandwidth_item_id')
->select(
'commission_item_prices.price as commission_price',
'commission_items.bandwidth_item_id',
'sales_invoice_items.product_id'
)
->distinct()
->get();
foreach ($commissionItemPrices as $price) {
$productId = (int)$price->product_id;
$bandwidthItemId = (int)$price->bandwidth_item_id;
$commissionItemPricesMap[$productId] = (float)$price->commission_price;
$commissionItemPricesMap[$bandwidthItemId] = (float)$price->commission_price;
}
}
// Get bandwidth item cost prices
$bandwidthItemPrices = \App\Models\BandwidthItemCostPrice::with('bandwidthItem')
->where('status', 'active')
->where('effective_date', '<=', $monthEnd)
->orderBy('effective_date', 'desc')
->get()
->groupBy('bandwidth_item_id')
->map(function($group) {
return $group->first();
});
$itemPricesMap = [];
foreach ($bandwidthItemPrices as $price) {
if ($price->bandwidthItem) {
$itemPricesMap[$price->bandwidthItem->name] = [
'cost_rate' => $price->cost_rate,
'gross_cost' => $price->gross_cost ?? 0,
];
}
}
// Create a map of sales_invoice_item_id => nttn_cost_item for quick lookup
$nttnCostItemsMap = [];
foreach($monthNttnCosts as $nttnCost) {
foreach($nttnCost->items as $nttnCostItem) {
if ($nttnCostItem->sales_invoice_item_id) {
$nttnCostItemsMap[$nttnCostItem->sales_invoice_item_id] = $nttnCostItem;
}
}
}
// Calculate profit/loss for this month (only for paid amount)
$bandwidthProfit = 0;
$nttnProfit = 0;
$bandwidthProfitWithoutGross = 0; // Track profit without gross cost
$totalGrossCost = 0; // Track total gross cost for this month
// Track Sales Cost and NTTN Cost separately for bandwidth and NTTN items (like loss-profit-details)
$bandwidthSalesCost = 0; // Track Sales Cost for bandwidth items
$bandwidthNttnCost = 0; // Track NTTN Cost for bandwidth items
$nttnSalesCost = 0; // Track Sales Cost for NTTN items
$nttnNttnCost = 0; // Track NTTN Cost for NTTN items
// Process bandwidth items (only calculate for paid portion) - matching loss-profit-details logic
foreach($monthInvoices as $invoice) {
// Get paid amount for this invoice
$invoicePaidAmount = $invoice->transections()->where('transaction_type', 'payment')->sum('amount');
if ($invoicePaidAmount <= 0) {
continue; // Skip unpaid invoices
}
// Calculate invoice paid ratio
$invoicePaidRatio = $invoice->invoice_amount > 0 ? ($invoicePaidAmount / $invoice->invoice_amount) : 0;
foreach($invoice->items as $item) {
$itemName = $item->item_name;
// Skip NTTN items
if (stripos($itemName, 'NTTN') !== false || stripos($itemName, 'F@H') !== false || stripos($itemName, 'Summit') !== false) {
continue;
}
$revenue = $item->total_amount;
// Apply paid ratio to revenue
$paidRevenue = $revenue * $invoicePaidRatio;
$revenueQty = $item->quantity;
$costPrice = $itemPricesMap[$itemName]['cost_rate'] ?? 0;
$grossCost = $itemPricesMap[$itemName]['gross_cost'] ?? 0;
// Get Sales Commission Item Price (like loss-profit-details)
$bandwidthItemId = $item->product_id;
$commissionPrice = 0;
$revenueAfterCommission = 0;
$fullRevenueAfterCommission = 0; // Full value for Gross Cost calculation
if ($bandwidthItemId && isset($commissionItemPricesMap) && is_array($commissionItemPricesMap)) {
$bandwidthItemIdInt = (int)$bandwidthItemId;
if (isset($commissionItemPricesMap[$bandwidthItemIdInt])) {
$commissionPrice = $commissionItemPricesMap[$bandwidthItemIdInt];
// Full value (not proportional) for Gross Cost calculation
$fullRevenueAfterCommission = $revenueQty * $commissionPrice;
// Proportional value for profit calculation
$revenueAfterCommission = $fullRevenueAfterCommission * $invoicePaidRatio;
}
}
// Get NTTN cost for this item from nttn_cost_items map
// Calculate full NTTN Cost first (like loss-profit-details)
$fullNttnCost = 0;
$costQty = 0;
if (isset($nttnCostItemsMap[$item->id])) {
$nttnCostItem = $nttnCostItemsMap[$item->id];
// Use full NTTN Cost value (like loss-profit-details)
$fullNttnCost = $nttnCostItem->total_cast_amount;
$costQty = $nttnCostItem->quantity;
}
// Apply paid ratio for proportional calculation
$itemNttnCost = $fullNttnCost * $invoicePaidRatio;
// Calculate Sales Cost (like loss-profit-details)
// Sales Cost = Cost Qty × Cost Price (if Cost Qty exists), Otherwise: Sales Cost = Sales Qty × Cost Price
// In loss-profit-details, Sales Cost is full value (not proportional)
$salesCost = 0;
if ($costQty > 0) {
$salesCost = $costQty * $costPrice;
} else {
$salesCost = $revenueQty * $costPrice;
}
// Track Sales Cost and NTTN Cost for bandwidth items (like loss-profit-details)
// Sales Cost is full value, NTTN Cost is also full value
$bandwidthSalesCost += $salesCost;
$bandwidthNttnCost += $fullNttnCost;
// Calculate Sales Revenue without NTTN (full value for Gross Cost calculation)
$fullRevenueWithoutNttn = $revenue - $fullNttnCost;
$revenueWithoutNttn = $paidRevenue - $itemNttnCost; // Proportional for profit calculation
// Calculate Gross Cost amount (like loss-profit-details)
// Use full revenue values (not proportional) for Gross Cost calculation
if ($fullRevenueAfterCommission > 0) {
$grossCostAmount = $fullRevenueAfterCommission * ($grossCost / 100);
} else if ($fullRevenueWithoutNttn > 0) {
$grossCostAmount = $fullRevenueWithoutNttn * ($grossCost / 100);
} else {
$grossCostAmount = $revenue * ($grossCost / 100);
}
// Track gross cost
$totalGrossCost += $grossCostAmount;
// Calculate Profit/Loss (BW & NTTN) = Paid Amount - (Sales Cost + Gross Cost + NTTN Cost)
// Apply paid ratio to Sales Cost and Gross Cost for proportional calculation
$proportionalSalesCost = $salesCost * $invoicePaidRatio;
$proportionalGrossCost = $grossCostAmount * $invoicePaidRatio;
// NTTN Cost is already proportional (itemNttnCost)
$profit = $paidRevenue - ($proportionalSalesCost + $proportionalGrossCost + $itemNttnCost);
// Calculate Profit/Loss (Without Gross) = Paid Amount - (Sales Cost + NTTN Cost)
// Use full Sales Cost and full NTTN Cost (not proportional) to match loss-profit-details totals
// Paid Amount is already proportional
$profitWithoutGross = $paidRevenue - ($salesCost + $fullNttnCost);
$bandwidthProfit += $profit;
$bandwidthProfitWithoutGross += $profitWithoutGross;
}
}
// Get NTTN links for this user
$nttnLinks = \App\Models\NttnLink::where('customer_id', $user->id)
->where('status', 'active')
->get();
// Create nttn links map
$nttnLinksMap = [];
foreach ($nttnLinks as $link) {
$nttnLinksMap[$link->link_name] = [
'cast_rate' => $link->cast_rate,
'cast_vat' => $link->cast_vat,
'cost_price' => $link->cast_rate + ($link->cast_rate * $link->cast_vat / 100),
];
}
// Create itemLinkNames and itemDescriptions maps for NTTN matching (like loss-profit-details)
$itemLinkNames = [];
$itemDescriptions = [];
foreach($monthNttnCosts as $nttnCost) {
foreach($nttnCost->items as $nttnCostItem) {
if ($nttnCostItem->link_name) {
$itemName = $nttnCostItem->item_name;
if (!isset($itemLinkNames[$itemName])) {
$itemLinkNames[$itemName] = [];
}
$itemLinkNames[$itemName][] = $nttnCostItem->link_name;
}
}
}
foreach($monthInvoices as $invoice) {
foreach($invoice->items as $item) {
$itemName = $item->item_name;
if ($item->description) {
if (!isset($itemDescriptions[$itemName])) {
$itemDescriptions[$itemName] = [];
}
$itemDescriptions[$itemName][] = $item->description;
}
}
}
// Process NTTN items (only calculate for paid portion) - matching loss-profit-details logic
foreach($monthInvoices as $invoice) {
// Get paid amount for this invoice
$invoicePaidAmount = $invoice->transections()->where('transaction_type', 'payment')->sum('amount');
if ($invoicePaidAmount <= 0) {
continue; // Skip unpaid invoices
}
// Calculate invoice paid ratio
$invoicePaidRatio = $invoice->invoice_amount > 0 ? ($invoicePaidAmount / $invoice->invoice_amount) : 0;
foreach($invoice->items as $item) {
$itemName = $item->item_name;
// Only process NTTN items
if (stripos($itemName, 'NTTN') === false && stripos($itemName, 'F@H') === false && stripos($itemName, 'Summit') === false) {
continue;
}
$revenue = $item->total_amount;
// Apply paid ratio to revenue
$paidRevenue = $revenue * $invoicePaidRatio;
$revenueQty = $item->quantity;
// Get NTTN cost for this item from nttn_cost_items map
// Calculate full NTTN Cost first (like loss-profit-details)
$fullNttnCost = 0;
if (isset($nttnCostItemsMap[$item->id])) {
$nttnCostItem = $nttnCostItemsMap[$item->id];
// Use full NTTN Cost value (like loss-profit-details)
$fullNttnCost = $nttnCostItem->total_cast_amount;
}
// Apply paid ratio for proportional calculation
$itemNttnCost = $fullNttnCost * $invoicePaidRatio;
// Find all matching nttn_links for this item (like loss-profit-details)
$matchedNttnLinks = [];
// First, try to match by link_name from nttn_cost_items (most accurate)
$linkNames = $itemLinkNames[$itemName] ?? [];
if (!empty($linkNames)) {
foreach($nttnLinks as $link) {
foreach($linkNames as $storedLinkName) {
if (trim(strtolower($storedLinkName)) === trim(strtolower($link->link_name))) {
$matchedNttnLinks[] = $link;
break;
}
}
}
}
// If no match found, try by item descriptions
if (empty($matchedNttnLinks)) {
$descriptions = $itemDescriptions[$itemName] ?? [];
foreach($nttnLinks as $link) {
foreach($descriptions as $description) {
if (stripos($description, $link->link_name) !== false ||
stripos($link->link_name, $description) !== false) {
$matchedNttnLinks[] = $link;
break;
}
}
}
}
// Final fallback: check if item name contains link_name or vice versa
if (empty($matchedNttnLinks)) {
foreach($nttnLinks as $link) {
if (stripos($itemName, $link->link_name) !== false ||
stripos($link->link_name, $itemName) !== false) {
$matchedNttnLinks[] = $link;
}
}
}
// Calculate cost price from individual links (like loss-profit-details)
$costPrice = 0;
if (!empty($matchedNttnLinks)) {
$totalCastAmount = 0;
$totalQuantity = 0;
foreach($matchedNttnLinks as $link) {
// Calculate cast for each individual link
$individualCast = $link->cast_rate + ($link->cast_rate * $link->cast_vat / 100);
// Add to total cast amount (cast * quantity for this link)
$totalCastAmount += $individualCast * $link->quantity;
$totalQuantity += $link->quantity;
}
// Calculate average cost price: total cast amount / total quantity
$costPrice = $totalQuantity > 0 ? $totalCastAmount / $totalQuantity : 0;
} else {
// Fallback: try direct match in nttnLinksMap
if (isset($nttnLinksMap[$itemName]) && $nttnLinksMap[$itemName]['cost_price'] > 0) {
$costPrice = $nttnLinksMap[$itemName]['cost_price'];
}
}
// Calculate Sales Cost = Cost Price × Sales Quantity
// In loss-profit-details, Sales Cost is full value (not proportional)
$salesCost = $costPrice * $revenueQty;
// Track Sales Cost and NTTN Cost for NTTN items (like loss-profit-details)
// Sales Cost is full value, NTTN Cost is also full value
$nttnSalesCost += $salesCost;
$nttnNttnCost += $fullNttnCost;
// Calculate Profit/Loss (BW & NTTN) = Paid Amount - (Sales Cost + Gross Cost + NTTN Cost)
// For NTTN items, Gross Cost = 0, so: Profit/Loss = Paid Amount - (Sales Cost + NTTN Cost)
// Apply paid ratio to Sales Cost for proportional calculation
$proportionalSalesCost = $salesCost * $invoicePaidRatio;
// NTTN Cost is already proportional (itemNttnCost)
$profit = $paidRevenue - ($proportionalSalesCost + $itemNttnCost);
$nttnProfit += $profit;
}
}
// Store Sales Cost, Gross Cost, and NTTN Cost separately for this month
// Total Sales Cost = Bandwidth Sales Cost + NTTN Sales Cost
// Total Gross Cost = Bandwidth Gross Cost (NTTN items don't have gross cost)
// Total NTTN Cost = Bandwidth NTTN Cost + NTTN NTTN Cost
$totalSalesCost = $bandwidthSalesCost + $nttnSalesCost;
$totalNttnCost = $bandwidthNttnCost + $nttnNttnCost;
$lossProfitData[$key]['sales_cost'] = $totalSalesCost;
$lossProfitData[$key]['gross_cost'] = $totalGrossCost;
$lossProfitData[$key]['nttn_cost'] = $totalNttnCost;
// Apply the formula: Profit/Loss (BW & NTTN) = Paid Amount - (Sales Cost + Gross Cost + NTTN Cost)
$totalPaidAmount = $lossProfitData[$key]['paid_amount'] ?? 0;
$lossProfitData[$key]['profit_loss'] = $totalPaidAmount - ($totalSalesCost + $totalGrossCost + $totalNttnCost);
// Apply the formula: Profit/Loss (Without Gross) = Paid Amount - (Sales Cost + NTTN Cost)
$lossProfitData[$key]['profit_loss_without_gross'] = $totalPaidAmount - ($totalSalesCost + $totalNttnCost);
$lossProfitData[$key]['sales_cost_plus_nttn_cost'] = $totalSalesCost + $totalNttnCost;
// Store Sales Cost + NTTN Cost sum for this month
$lossProfitData[$key]['sales_cost_plus_nttn_cost'] = $totalSalesCost + $totalNttnCost;
// Calculate actual Cost of Goods Sold from profit/loss calculation
// COGS = Sales Revenue - Gross Profit (where Gross Profit = Profit/Loss)
// But we need to calculate total costs from the profit/loss calculation
// Total Costs = Sales Revenue - Profit/Loss
$totalProfitLoss = $lossProfitData[$key]['profit_loss'];
$actualCostOfGoods = $data['sales_revenue'] - $totalProfitLoss;
$lossProfitData[$key]['cost_of_goods'] = $actualCostOfGoods;
// Calculate Gross Profit and Margin for each month
$lossProfitData[$key]['gross_profit'] = $data['sales_revenue'] - $actualCostOfGoods;
if ($data['sales_revenue'] > 0) {
$lossProfitData[$key]['gross_profit_margin'] = round(($lossProfitData[$key]['gross_profit'] / $data['sales_revenue']) * 100, 2);
} else {
$lossProfitData[$key]['gross_profit_margin'] = 0;
}
// Store month key for action link
$lossProfitData[$key]['month_key'] = $key;
}
// Sort by month (newest first)
krsort($lossProfitData);
// Calculate totals
$totalSalesRevenue = collect($lossProfitData)->sum('sales_revenue');
$totalPaidAmount = collect($lossProfitData)->sum('paid_amount');
$totalProfitLossBW = collect($lossProfitData)->sum('profit_loss');
$totalProfitLossNTTN = collect($lossProfitData)->sum('profit_loss_nttn');
$totalCostOfGoods = collect($lossProfitData)->sum('cost_of_goods');
$totalGrossProfit = $totalSalesRevenue - $totalCostOfGoods;
$totalGrossProfitMargin = $totalSalesRevenue > 0 ? round(($totalGrossProfit / $totalSalesRevenue) * 100, 2) : 0;
// Store lossProfitData for JavaScript chart
$chartLossProfitData = $lossProfitData;
@endphp
@foreach($lossProfitData as $monthKey => $monthData)
| {{ $monthData['month'] }} |
৳ {{ number_format($monthData['sales_revenue'], 2) }} |
৳ {{ number_format($monthData['paid_amount'] ?? 0, 2) }} |
৳ {{ number_format($monthData['sales_cost'] ?? 0, 2) }}
|
৳ {{ number_format($monthData['gross_cost'] ?? 0, 2) }}
|
৳ {{ number_format($monthData['nttn_cost'] ?? 0, 2) }}
|
৳ {{ number_format($monthData['profit_loss'] ?? 0, 2) }}
|
৳ {{ number_format($monthData['profit_loss_without_gross'] ?? 0, 2) }}
|
{{ $monthData['gross_profit_margin'] }}%
|
@if(($monthData['profit_loss_without_gross'] ?? 0) >= 0)
Profit
@else
Loss
@endif
|
|
@endforeach
@if(empty($lossProfitData))
| No data available for Loss & Profit analysis |
@else
@php
$totalProfitLossWithoutGross = collect($lossProfitData)->sum('profit_loss_without_gross');
$totalSalesCost = collect($lossProfitData)->sum('sales_cost');
$totalGrossCost = collect($lossProfitData)->sum('gross_cost');
$totalNttnCost = collect($lossProfitData)->sum('nttn_cost');
$totalPaidAmount = collect($lossProfitData)->sum('paid_amount');
@endphp
| Total |
৳ {{ number_format($totalSalesRevenue, 2) }} |
৳ {{ number_format($totalPaidAmount, 2) }} |
৳ {{ number_format($totalSalesCost, 2) }}
|
৳ {{ number_format($totalGrossCost, 2) }}
|
৳ {{ number_format($totalNttnCost, 2) }}
|
৳ {{ number_format($totalProfitLossBW, 2) }}
|
৳ {{ number_format($totalProfitLossWithoutGross, 2) }}
|
{{ $totalGrossProfitMargin }}%
|
@if($totalGrossProfit >= 0)
Net Profit
@else
Net Loss
@endif
|
|
@endif
To
{{ $user->name }}
@if($user->company_name)
{{ $user->company_name }}
@endif
{{ $user->address ?? '' }}
{{ $user->phone ?? '' }}
{{ $user->email ?? '' }}
NetX Internet
Bangladesh
revenue.netx@gmail.com
Statement of Accounts
{{ $statementData['statement_period_start']->format('d M Y') }} To {{ $statementData['statement_period_end']->format('d M Y') }}
| Account Summary |
| Opening Balance: |
BDT {{ number_format(0, 2) }} |
| Invoiced Amount: |
BDT {{ number_format($statementData['total_invoice_amount'], 2) }} |
| Amount Received: |
BDT {{ number_format($statementData['total_paid_amount'], 2) }} |
| Balance Due: |
BDT {{ number_format(max(0, $statementData['total_invoice_amount'] - $statementData['total_paid_amount']), 2) }}
|
| Advance Amount: |
BDT {{ number_format($statementData['advance_amount'], 2) }}
|
| Date |
Details |
Transactions |
Amount |
Payments |
Balance |
@php
$runningBalance = 0;
$allTransactions = collect();
// Add opening balance
$allTransactions->push([
'date' => $statementData['statement_period_start'],
'type' => 'Opening Balance',
'details' => '',
'amount' => 0,
'payment' => 0,
'balance' => 0
]);
// Add invoices
foreach($salesInvoices as $invoice) {
$runningBalance += $invoice->invoice_amount;
$allTransactions->push([
'date' => $invoice->invoice_date,
'type' => 'Invoice',
'details' => $invoice->invoice_no,
'amount' => $invoice->invoice_amount,
'payment' => 0,
'balance' => $runningBalance
]);
}
// Add payments
foreach($paymentTransactions as $transaction) {
if($transaction->transaction_type === 'payment') {
$runningBalance -= $transaction->amount;
$allTransactions->push([
'date' => $transaction->transaction_date,
'type' => 'Payment Received',
'details' => $transaction->salesInvoice ? $transaction->salesInvoice->invoice_no : 'N/A',
'amount' => 0,
'payment' => $transaction->amount,
'balance' => $runningBalance
]);
}
}
// Sort by date, but keep Opening Balance at top
$allTransactions = $allTransactions->sortBy(function($transaction) {
if($transaction['type'] === 'Opening Balance') {
return '0000-00-00'; // Always first
}
return $transaction['date']->format('Y-m-d');
})->values();
// Recalculate running balance after sorting
$currentBalance = 0;
$allTransactionsArray = $allTransactions->toArray();
foreach($allTransactionsArray as $index => $transaction) {
if($transaction['type'] === 'Opening Balance') {
$currentBalance = 0;
} elseif($transaction['type'] === 'Invoice') {
$currentBalance += $transaction['amount'];
} elseif($transaction['type'] === 'Payment Received') {
$currentBalance -= $transaction['payment'];
}
// Update the balance for this transaction
$allTransactionsArray[$index]['balance'] = $currentBalance;
}
$allTransactions = collect($allTransactionsArray);
@endphp
@foreach($allTransactions as $index => $transaction)
| {{ $transaction['date']->format('d M Y') }} |
{!! $transaction['details'] !!} |
@if($transaction['type'] === 'Opening Balance')
***Opening Balance***
@else
{{ $transaction['type'] }}
@endif
|
@if($transaction['amount'] > 0)
{{ number_format($transaction['amount'], 2) }}
@endif
|
@if($transaction['payment'] > 0)
{{ number_format($transaction['payment'], 2) }}
@endif
|
{{ number_format($transaction['balance'], 2) }}
|
@endforeach
This statement was generated on {{ now()->format('d M Y H:i:s') }}
For any queries, please contact us at revenue.netx@gmail.com
Sales Invoices Summary
Total Sales Invoices:
0
Paid Invoices:
0
Pending Invoices:
0
Overdue Invoices:
0
Last Sales Invoice:
Never
Total Sales Amount:
৳0.00
Outstanding Sales:
৳0.00
Sales Invoices Details
No sales invoices found
This reseller has no product or service sales invoices.
Invoice Types:
Product Sales, Service Sales
Payment Terms:
Net 30
Tax Rate:
15%
Recent Activity
Account Created:
{{ $user->created_at->format('d M Y H:i') }}
Profile Last Updated:
{{ $user->updated_at->format('d M Y H:i') }}
Last Login:
{{ $user->last_login_at ? $user->last_login_at->format('d M Y H:i') : 'Never logged in' }}
Account Age:
{{ $user->created_at->diffForHumans() }}
Days Since Last Login:
{{ $user->last_login_at ? $user->last_login_at->diffInDays(now()) . ' days ago' : 'Never' }}
Assigned Employees
@if($user->assignedEmployees && $user->assignedEmployees->count() > 0)
| SN |
Employee Name |
Position |
Email |
Phone |
Assigned On |
Actions |
@foreach($user->assignedEmployees as $index => $employee)
| {{ $index + 1 }} |
{{ $employee->name }}
ID: {{ $employee->id }}
|
@if($employee->position)
{{ $employee->position }}
@else
-
@endif
|
@if($employee->email)
{{ $employee->email }}
@else
-
@endif
|
{{ $employee->phone ?? '-' }} |
{{ $employee->pivot->created_at->format('d M Y') }}
|
|
@endforeach
@else
No employees assigned
This reseller doesn't have any employees assigned to take care of them.
@endif
Total Ticket
{{ $totalTicketsCount ?? 0 }}
Solved Ticket
{{ $solvedTicketsCount ?? 0 }}
Closed Ticket
{{ $closedTicketsCount ?? 0 }}
@if($categoryWiseStats->count() > 0)
Showing data from {{ $categoryDateFrom->format('M d, Y') }} to {{ $categoryDateTo->format('M d, Y') }}
| Category |
Total |
Solved |
Pending |
Avg Assigned Time |
Avg Solved Time |
@foreach($categoryWiseStats as $stat)
|
{{ $stat['category_name'] }}
|
{{ $stat['total_tickets'] }} |
{{ $stat['solved_tickets'] }} |
{{ $stat['pending_tickets'] }} |
@if($stat['avg_assigned_time'] > 0)
@php
$assignedHours = floor($stat['avg_assigned_time'] / 3600);
$assignedMinutes = floor(($stat['avg_assigned_time'] % 3600) / 60);
$assignedSeconds = $stat['avg_assigned_time'] % 60;
@endphp
{{ $assignedHours }}h {{ $assignedMinutes }}m {{ $assignedSeconds }}s
@else
N/A
@endif
|
@if($stat['avg_solved_time'] > 0)
@php
$solvedHours = floor($stat['avg_solved_time'] / 3600);
$solvedMinutes = floor(($stat['avg_solved_time'] % 3600) / 60);
$solvedSeconds = $stat['avg_solved_time'] % 60;
@endphp
{{ $solvedHours }}h {{ $solvedMinutes }}m {{ $solvedSeconds }}s
@else
N/A
@endif
|
@endforeach
| Total |
{{ $categoryWiseStats->sum('total_tickets') }}
|
{{ $categoryWiseStats->sum('solved_tickets') }}
|
{{ $categoryWiseStats->sum('pending_tickets') }}
|
@php
$totalAssignedSeconds = 0;
$assignedCount = 0;
foreach($categoryWiseStats as $stat) {
if($stat['avg_assigned_time'] > 0) {
$totalAssignedSeconds += $stat['avg_assigned_time'];
$assignedCount++;
}
}
$overallAvgAssignedTime = $assignedCount > 0 ? $totalAssignedSeconds / $assignedCount : 0;
$assignedHours = floor($overallAvgAssignedTime / 3600);
$assignedMinutes = floor(($overallAvgAssignedTime % 3600) / 60);
$assignedSeconds = $overallAvgAssignedTime % 60;
@endphp
@if($overallAvgAssignedTime > 0)
{{ $assignedHours }}h {{ $assignedMinutes }}m {{ $assignedSeconds }}s
@else
N/A
@endif
|
@php
$totalSolvedSeconds = 0;
$solvedCount = 0;
foreach($categoryWiseStats as $stat) {
if($stat['avg_solved_time'] > 0) {
$totalSolvedSeconds += $stat['avg_solved_time'];
$solvedCount++;
}
}
$overallAvgSolvedTime = $solvedCount > 0 ? $totalSolvedSeconds / $solvedCount : 0;
$solvedHours = floor($overallAvgSolvedTime / 3600);
$solvedMinutes = floor(($overallAvgSolvedTime % 3600) / 60);
$solvedSeconds = $overallAvgSolvedTime % 60;
@endphp
@if($overallAvgSolvedTime > 0)
{{ $solvedHours }}h {{ $solvedMinutes }}m {{ $solvedSeconds }}s
@else
N/A
@endif
|
| SL |
Issues |
Created Ticket |
Solved Ticket |
Average Assign Time |
Average Forwarded Time |
Average Solved Time |
@if($allIssues->count() > 0)
@php
$statusColors = [
'upstream_issues' => '#cfe2ff',
'pop_issues' => '#ffe5d0',
'transmission_issues' => '#e2d9f3'
];
$statusTextColors = [
'upstream_issues' => '#084298',
'pop_issues' => '#b45309',
'transmission_issues' => '#5a32a3'
];
@endphp
@foreach($allIssues as $index => $issueData)
@php
$statusColor = $statusColors[$issueData['status']] ?? '#e9ecef';
$statusTextColor = $statusTextColors[$issueData['status']] ?? '#495057';
@endphp
| {{ $index + 1 }} |
{{ $issueData['status_label'] }}
|
{{ $issueData['created_count'] }}
|
{{ $issueData['solved_count'] }}
|
@if($issueData['avg_assign_time'] !== '-')
{{ $issueData['avg_assign_time'] }}
@else
-
@endif
|
@if($issueData['avg_forwarded_time'] !== '-')
{{ $issueData['avg_forwarded_time'] }}
@else
-
@endif
|
@if($issueData['avg_solved_time'] !== '-')
{{ $issueData['avg_solved_time'] }}
@else
-
@endif
|
@endforeach
@else
|
No issues found.
|
@endif
| SL |
Ticket # |
Subject |
Category |
Sub Category |
Priority |
Status |
Level |
Solved Time |
Actions |
@php
$statusColors = [
'open' => '#28a745',
'in_progress' => '#ffc107',
'upstream_issues' => '#007bff',
'pop_issues' => '#fd7e14',
'transmission_issues' => '#6f42c1',
'resolved' => '#6c757d',
'closed' => '#343a40'
];
$priorityColors = [
'low' => '#28a745',
'medium' => '#ffc107',
'high' => '#fd7e14',
'urgent' => '#dc3545'
];
@endphp
@forelse($tickets as $index => $ticket)
@php
$statusColor = $statusColors[$ticket->status] ?? '#6c757d';
$priorityColor = $priorityColors[$ticket->priority] ?? '#6c757d';
$statusLabels = [
'open' => 'Open',
'in_progress' => 'In Progress',
'upstream_issues' => 'Upstream Issues',
'pop_issues' => 'POP Issues',
'transmission_issues' => 'Transmission Issues',
'resolved' => 'Resolved',
'closed' => 'Closed'
];
$statusLabel = $statusLabels[$ticket->status] ?? ucfirst(str_replace('_', ' ', $ticket->status));
// Calculate solved time
$solvedTime = null;
if ($ticket->resolved_at) {
$solvedTime = $ticket->created_at->diffInMinutes($ticket->resolved_at);
} elseif (in_array($ticket->status, ['resolved', 'closed']) && $ticket->closed_at) {
$solvedTime = $ticket->created_at->diffInMinutes($ticket->closed_at);
}
$solvedTimeFormatted = '-';
if ($solvedTime !== null) {
$days = floor($solvedTime / (24 * 60));
$hours = floor(($solvedTime % (24 * 60)) / 60);
$minutes = $solvedTime % 60;
$seconds = 0;
$solvedTimeFormatted = sprintf('%dd:%02dh:%02dm:%02ds', $days, $hours, $minutes, $seconds);
}
@endphp
| {{ ($tickets->currentPage() - 1) * $tickets->perPage() + $index + 1 }} |
{{ $ticket->ticket_number }}
|
{{ Str::limit($ticket->subject, 50) }} |
{{ $ticket->category->name ?? 'N/A' }} |
{{ $ticket->subcategory->name ?? 'N/A' }} |
{{ ucfirst($ticket->priority) }}
|
{{ $statusLabel }}
|
@php
$activeAssignment = $ticket->assignedEmployees->where('pivot.is_active', true)->first();
$isSolved = $ticket->resolved_at || in_array($ticket->status, ['resolved', 'closed']);
@endphp
@if($isSolved)
Solved
@elseif($activeAssignment)
{{ $activeAssignment->name }}
@else
Unassigned
@endif
|
@if($solvedTimeFormatted !== '-')
{{ $solvedTimeFormatted }}
@else
-
@endif
|
|
@empty
|
No tickets found for this user.
|
@endforelse
@if($tickets->hasPages())
@endif
@endif
Total Links
{{ $nttnLinks->count() }}
Active Links
{{ $nttnLinks->where('status', 'active')->count() }}
Total Sell Amount
@php
$totalSellAmount = $nttnLinks->sum(function($link) {
return ($link->sell_rate + ($link->sell_rate * $link->sell_vat / 100)) * $link->quantity;
});
@endphp
৳ {{ number_format($totalSellAmount, 2) }}
Total Profit/Loss
@php
$totalCastAmount = $nttnLinks->sum(function($link) {
return ($link->cast_rate + ($link->cast_rate * $link->cast_vat / 100)) * $link->quantity;
});
$totalProfitLoss = $totalSellAmount - $totalCastAmount;
@endphp
৳ {{ number_format($totalProfitLoss, 2) }}
@if($nttnLinks->count() > 0)
| SL |
Link Name |
Bandwidth Item |
Quantity |
Sell Rate |
Sell VAT |
Total Sell Amount |
Cast Rate |
Cast VAT |
Total Cast Amount |
Profit/Loss |
Status |
Action |
@foreach($nttnLinks as $index => $link)
@php
$totalSellAmountItem = ($link->sell_rate + ($link->sell_rate * $link->sell_vat / 100)) * $link->quantity;
$totalCastAmountItem = ($link->cast_rate + ($link->cast_rate * $link->cast_vat / 100)) * $link->quantity;
$profitLossItem = $totalSellAmountItem - $totalCastAmountItem;
@endphp
| {{ $index + 1 }} |
{{ $link->link_name }}
@if($link->description)
{{ Str::limit($link->description, 30) }}
@endif
|
{{ $link->item->name ?? '-' }} |
{{ number_format($link->quantity, 2) }} |
৳ {{ number_format($link->sell_rate, 2) }} |
{{ number_format($link->sell_vat, 2) }}% |
৳ {{ number_format($totalSellAmountItem, 2) }}
|
৳ {{ number_format($link->cast_rate, 2) }} |
{{ number_format($link->cast_vat, 2) }}% |
৳ {{ number_format($totalCastAmountItem, 2) }}
|
৳ {{ number_format($profitLossItem, 2) }}
|
@if($link->status == 'active')
Active
@else
Inactive
@endif
|
|
@endforeach
| Total: |
{{ number_format($nttnLinks->sum('quantity'), 2) }}
|
- |
৳ {{ number_format($totalSellAmount, 2) }}
|
- |
৳ {{ number_format($totalCastAmount, 2) }}
|
৳ {{ number_format($totalProfitLoss, 2) }}
|
- |
- |
@else
No NTTN Links found for this user.
@endif
Total Links
{{ $nttnDataLinks->count() }}
Active Links
{{ $nttnDataLinks->where('status', 'active')->count() }}
Total Quantity
@php
$totalQuantity = $nttnDataLinks->sum('quantity');
@endphp
{{ number_format($totalQuantity, 2) }}
Total Sell Amount
@php
$totalSellAmountData = $nttnDataLinks->sum(function($link) {
return ($link->sell_rate + ($link->sell_rate * $link->sell_vat / 100)) * $link->quantity;
});
@endphp
৳ {{ number_format($totalSellAmountData, 2) }}
@if($nttnDataLinks->count() > 0)
| SL |
Link Name |
From POP |
To POP |
Quantity |
Sell Rate |
Sell VAT |
Total Sell Amount |
Status |
Action |
@foreach($nttnDataLinks as $index => $link)
@php
$totalSellAmountItem = ($link->sell_rate + ($link->sell_rate * $link->sell_vat / 100)) * $link->quantity;
@endphp
| {{ $index + 1 }} |
{{ $link->link_name }}
@if($link->description)
{{ Str::limit($link->description, 30) }}
@endif
|
{{ $link->from_pop_name ?? '-' }}
@if($link->from_port_number)
Port: {{ $link->from_port_number }}
@endif
|
{{ $link->to_pop_name ?? '-' }}
@if($link->to_port_number)
Port: {{ $link->to_port_number }}
@endif
|
{{ number_format($link->quantity, 2) }} |
৳ {{ number_format($link->sell_rate, 2) }} |
{{ number_format($link->sell_vat, 2) }}% |
৳ {{ number_format($totalSellAmountItem, 2) }}
|
@if($link->status == 'active')
Active
@else
Inactive
@endif
|
|
@endforeach
| Total: |
{{ number_format($totalQuantity, 2) }}
|
- |
৳ {{ number_format($totalSellAmountData, 2) }}
|
- |
- |
@else
No Data Links found for this user.
@endif
@if($nttnDataLinks->count() > 0)
| SL |
Link Name |
From POP |
From Switch/Router |
From Port |
From Port Capacity |
From SFP Serial |
To POP |
To Switch/Router |
To Port |
To Port Capacity |
To Port Traffic Usage |
To SFP Serial |
Action |
@foreach($nttnDataLinks as $index => $link)
| {{ $index + 1 }} |
{{ $link->link_name }} |
{{ $link->from_pop_name ?? '-' }} |
{{ $link->from_switch_or_router ?? '-' }} |
{{ $link->from_port_number ?? '-' }} |
{{ $link->from_port_capacity ?? '-' }} |
{{ $link->from_sfp_serial ?? '-' }} |
{{ $link->to_pop_name ?? '-' }} |
{{ $link->to_switch_or_router ?? '-' }} |
{{ $link->to_port_number ?? '-' }} |
{{ $link->to_port_capacity ?? '-' }} |
@php
$trafficUsage = $link->to_port_traffic_usage ?? '';
@endphp
{{ $trafficUsage ?: '-' }}
|
{{ $link->to_sfp_serial ?? '-' }} |
|
@endforeach
@endif