@extends('layouts.app') @section('title', 'Reseller Tickets') @section('content')

Reseller Tickets

Manage reseller support tickets

@if($isSuperAdmin || $isAdmin || $isEmployee) Issues Report Category Reports Report @endif Create New Ticket
@if(isset($currentEmployee) && $currentEmployee) @else @if(isset($isReseller) && $isReseller)

{{ $resellerTotalSolvedCount ?? 0 }}

Total Solved

@endif @endif @if($isSuperAdmin || $isAdmin)

{{ $averageAssignTime ?? '0d:00h:00m:00s' }}

Average Assign Time

{{ $averageForwardedTime ?? '0d:00h:00m:00s' }}

Average Forwarded Time

{{ $averageSolvedTime ?? '0d:00h:00m:00s' }}

Average Solved Time

@endif @if(isset($isReseller) && $isReseller)

{{ $createdByMeCount ?? 0 }}

Created by Me

@endif
@if(($isSuperAdmin || $isAdmin) && request('per_page')) @endif
@if(isset($currentEmployee) && $currentEmployee && isset($assignedTickets) && $assignedTickets->count() > 0)
My Assigned Tickets ({{ $assignedTickets->count() }})
@foreach($assignedTickets as $ticket) @endforeach
Ticket # Reseller Priority Status Assign To Category Assigned At Created At Duration Actions
{{ $ticket->ticket_number }} @if($ticket->user->reseller && $ticket->user->reseller->name) {{ $ticket->user->reseller->name }} @elseif($ticket->user->company_name) {{ $ticket->user->company_name }} @else {{ $ticket->user->name ?? 'N/A' }} @endif @php $priorityColors = [ 'low' => '#6c757d', 'medium' => '#17a2b8', 'high' => '#ffc107', 'urgent' => '#dc3545' ]; $priorityColor = $priorityColors[$ticket->priority] ?? '#6c757d'; @endphp {{ ucfirst($ticket->priority) }} @php $statusLabel = in_array($ticket->status, ['resolved', 'closed']) ? 'Solved' : ucfirst(str_replace('_', ' ', $ticket->status)); // For resellers, exclude 'in_progress' from clickable statuses $clickableStatuses = isset($isReseller) && $isReseller ? ['upstream_issues', 'pop_issues', 'transmission_issues'] : ['in_progress', 'upstream_issues', 'pop_issues', 'transmission_issues']; $isClickable = in_array($ticket->status, $clickableStatuses); $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; $statusColors = [ 'in_progress' => '#ffc107', 'upstream_issues' => '#007bff', 'pop_issues' => '#fd7e14', 'transmission_issues' => '#6f42c1' ]; $statusColor = $statusColors[$ticket->status] ?? '#6c757d'; @endphp @if($ticket->status == 'in_progress' && (isset($isReseller) && $isReseller)) {{-- For resellers, show in_progress status as non-clickable --}} In Progress @elseif($isClickable && !$isSolved) {{ $statusLabel }} @elseif($isClickable && $isSolved) {{ $statusLabel }} @else {{ $statusLabel }} @endif @php // Current active assignment for this employee (in this page context currentEmployee exists) $currentAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('employee_id', $currentEmployee->id) ->where('is_active', true) ->first(); // Was it forwarded (previous inactive assignment exists for someone else)? $hasPreviousAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('employee_id', '!=', $currentEmployee->id) ->where('is_active', false) ->exists(); $forwardedTo = null; $forwardedBy = null; $assignedBy = null; if ($currentAssignment) { if ($currentAssignment->assigned_by) { $assignedByUser = \App\Models\User::find($currentAssignment->assigned_by); $assignedBy = $assignedByUser ? $assignedByUser->name : 'N/A'; } if ($hasPreviousAssignment) { $forwardedTo = $currentEmployee->name; $forwardedBy = $assignedBy; } } @endphp @if($currentAssignment) @if($ticket->resolved_at) {{-- Ticket is solved, show Solved instead of Forwarded --}} @elseif($hasPreviousAssignment && $forwardedTo && $forwardedBy) @else @endif @else N/A @endif {{ $ticket->category->name ?? 'N/A' }} @php $assignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('employee_id', $currentEmployee->id) ->where('is_active', true) ->first(); @endphp @if($assignment && $assignment->assigned_at) {{ \Carbon\Carbon::parse($assignment->assigned_at)->diffForHumans() }} @else N/A @endif {{ $ticket->created_at->format('Y-m-d H:i') }} @php // Calculate duration from created_at to resolved_at/closed_at or now $createdAt = \Carbon\Carbon::parse($ticket->created_at); if ($ticket->resolved_at || $ticket->closed_at) { $endAt = \Carbon\Carbon::parse($ticket->resolved_at ?? $ticket->closed_at); } else { $endAt = now(); } $diff = $createdAt->diff($endAt); $duration = sprintf('%dd:%02dh:%02dm:%02ds', $diff->days, $diff->h, $diff->i, $diff->s ); $startIso = $createdAt->toIso8601String(); $isStatic = ($ticket->resolved_at || $ticket->closed_at) ? true : false; $endIso = $isStatic ? $endAt->toIso8601String() : null; @endphp {{ $duration }} @if(isset($assignedTicketNotificationCounts[$ticket->id]) && $assignedTicketNotificationCounts[$ticket->id] > 0) {{ $assignedTicketNotificationCounts[$ticket->id] }} @endif @if($ticket->status !== 'resolved' && $ticket->status !== 'closed') @if(isset($employeeMessageNotificationCounts[$ticket->id]) && $employeeMessageNotificationCounts[$ticket->id] > 0) {{ $employeeMessageNotificationCounts[$ticket->id] }} @endif @endif
@endif @if(isset($assignedTickets) && $assignedTickets->count() > 0) @foreach($assignedTickets as $ticket) @php // For resellers, exclude 'in_progress' from clickable statuses $clickableStatuses = isset($isReseller) && $isReseller ? ['upstream_issues', 'pop_issues', 'transmission_issues'] : ['in_progress', 'upstream_issues', 'pop_issues', 'transmission_issues']; $shouldShowModal = in_array($ticket->status, $clickableStatuses); @endphp @if($shouldShowModal) @endif @endforeach @endif {{-- Assign Modal for My Assigned Tickets --}} @if(isset($currentEmployee) && $currentEmployee && isset($assignedTickets) && $assignedTickets->count() > 0) @foreach($assignedTickets as $ticket) @php // Current assignment details for preselects $currentAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('is_active', true) ->first(); $currentDepartmentId = $currentAssignment ? $currentAssignment->department_id : null; $currentEmployeeId = $currentAssignment ? $currentAssignment->employee_id : null; $hasExistingAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->exists(); // Department options - only show employee's own ISP departments $currentUser = auth()->user(); $currentUser->load('employeeRecord'); $currentEmployeeForModal = $currentUser->employeeRecord; $checkSuperAdmin = $currentUser->role === 'super_admin' || in_array(strtolower($currentUser->role), ['super_admin', 'super-admin', 'super admin']) || in_array($currentUser->email, ['mkzwasim@gmail.com', 'sahrior@gmail.com', 'wasim@mkz.com.bd']); if ($checkSuperAdmin || (isset($isSuperAdmin) && $isSuperAdmin)) { // Super admin sees all departments $departments = \App\Models\Department::where('is_active', true) ->orderBy('name') ->get(); } elseif ($currentEmployeeForModal && $currentEmployeeForModal->department_id) { // Employee sees departments from their ISP (via their department's ISP) $employeeDepartment = \App\Models\Department::find($currentEmployeeForModal->department_id); if ($employeeDepartment && $employeeDepartment->isp_id) { $departments = \App\Models\Department::where('is_active', true) ->where('isp_id', '=', $employeeDepartment->isp_id) ->whereNotNull('isp_id') ->orderBy('name') ->get(); } else { // If employee department has no ISP, show empty (no fallback to all) $departments = collect(); } } elseif ($currentUser->branch_id) { // Regular users see only departments from their ISP $departments = \App\Models\Department::where('is_active', true) ->where('isp_id', '=', $currentUser->branch_id) ->whereNotNull('isp_id') ->orderBy('name') ->get(); } else { // No branch_id and no employee record - show empty (no fallback) $departments = collect(); } $employees = $currentDepartmentId ? \App\Models\Employee::where('department_id', $currentDepartmentId)->where('status', true)->orderBy('name')->get() : collect(); @endphp @endforeach @endif @if(isset($currentEmployee) && $currentEmployee && isset($assignedTickets) && $assignedTickets->count() > 0) @foreach($assignedTickets as $ticket) @endforeach @endif @if(isset($currentEmployee) && $currentEmployee && isset($assignedTickets) && $assignedTickets->count() > 0) @foreach($assignedTickets as $ticket) @if($ticket->status !== 'resolved' && $ticket->status !== 'closed') @endif @endforeach @endif
All Tickets
@if($isSuperAdmin || $isAdmin || (isset($isReseller) && $isReseller))
SHOW
@if(request('search')) @endif @if(request('status')) @endif @if(request('priority')) @endif @if(request('category_id')) @endif @if(request('department_id')) @endif @if(request('employee_id')) @endif
ENTRIES
@endif
@if($isSuperAdmin || $isAdmin) @endif @if(!isset($isReseller) || !$isReseller) @endif @if(isset($isReseller) && $isReseller) @endif @forelse($tickets as $index => $ticket) @php $slNumber = ($tickets->currentPage() - 1) * $tickets->perPage() + $index + 1; @endphp @php $isAssignedToMe = isset($assignedTicketIds) && in_array($ticket->id, $assignedTicketIds); // Calculate duration from created_at to resolved_at/closed_at or now $createdAt = \Carbon\Carbon::parse($ticket->created_at); if ($ticket->resolved_at || $ticket->closed_at) { $endAt = \Carbon\Carbon::parse($ticket->resolved_at ?? $ticket->closed_at); } else { $endAt = now(); } $diff = $createdAt->diff($endAt); $solvedDuration = sprintf('%dd:%02dh:%02dm:%02ds', $diff->days, $diff->h, $diff->i, $diff->s ); @endphp @if($isSuperAdmin || $isAdmin) @endif @if(!isset($isReseller) || !$isReseller) @endif @if(isset($isReseller) && $isReseller) @endif @empty @php $colCount = 8; // Base: SL, Reseller, Problem, Sub Category, Priority, Assign To, Created by, Actions if ($isSuperAdmin || $isAdmin) { $colCount += 2; // Mobile, Complained Number } if (!isset($isReseller) || !$isReseller) { $colCount += 1; // Status } if (isset($isReseller) && $isReseller) { $colCount += 1; // Solved by } @endphp @endforelse
SL ResellerMobile(Existing) Complained NumberProblem Sub Category PriorityStatusAssign ToSolved byCreated by Actions
{{ $slNumber }} @if($ticket->user->reseller && $ticket->user->reseller->name) {{ $ticket->user->reseller->name }} @elseif($ticket->user->company_name) {{ $ticket->user->company_name }} @else {{ $ticket->user->name ?? 'N/A' }} @endif {{ $ticket->user->phone ?? 'N/A' }} @if($ticket->complained_number) {{ $ticket->complained_number }} @else N/A @endif {{ $ticket->category->name ?? ($ticket->description ? Str::limit($ticket->description, 30) : 'N/A') }} {{ $ticket->subcategory->name ?? 'N/A' }} @php $priorityColors = [ 'low' => '#6c757d', 'medium' => '#17a2b8', 'high' => '#ffc107', 'urgent' => '#dc3545' ]; $priorityColor = $priorityColors[$ticket->priority] ?? '#6c757d'; @endphp {{ ucfirst($ticket->priority) }} @php // For resellers, exclude 'in_progress' from clickable statuses $clickableStatuses = isset($isReseller) && $isReseller ? ['upstream_issues', 'pop_issues', 'transmission_issues'] : ['in_progress', 'upstream_issues', 'pop_issues', 'transmission_issues']; $isClickable = in_array($ticket->status, $clickableStatuses); $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; $statusColors = [ 'in_progress' => '#ffc107', 'upstream_issues' => '#007bff', 'pop_issues' => '#fd7e14', 'transmission_issues' => '#6f42c1' ]; $statusColor = $statusColors[$ticket->status] ?? '#6c757d'; @endphp @if($ticket->status == 'in_progress' && (isset($isReseller) && $isReseller)) {{-- For resellers, show in_progress status as non-clickable --}} In Progress @elseif($isClickable && !$isSolved) @if($isEmployee && $ticket->status == 'in_progress') {{ ucfirst(str_replace('_', ' ', $ticket->status)) }} @else {{ ucfirst(str_replace('_', ' ', $ticket->status)) }} @endif @elseif($isClickable && $isSolved) {{ ucfirst(str_replace('_', ' ', $ticket->status)) }} @else {{ ucfirst(str_replace('_', ' ', $ticket->status)) }} @endif @php // Check if ticket has been assigned before $hasAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->exists(); // Check if ticket has been forwarded (has inactive assignments) $hasInactiveAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('is_active', false) ->exists(); // Determine button text and color $buttonColor = '#007bff'; // Default blue $buttonDisabled = false; // If ticket is resolved or closed, show "Solved" and disable button // Also check if ticket has resolved_at timestamp (solved from restricted status) if ($ticket->status === 'resolved' || $ticket->status === 'closed' || $ticket->resolved_at) { $buttonText = 'Solved'; $buttonTitle = 'Solved'; $buttonColor = '#6c757d'; // Gray color for solved $buttonDisabled = true; } elseif ($hasInactiveAssignment) { // Ticket has been forwarded/re-assigned $buttonText = 'Forwarded'; $buttonTitle = 'Forwarded'; $buttonColor = '#28a745'; // Green color for forwarded } elseif ($hasAssignment) { // Ticket has been assigned but not forwarded $buttonText = 'Re-Assign'; $buttonTitle = 'Re-Assign'; $buttonColor = '#007bff'; // Blue color } else { // New ticket, never assigned $buttonText = 'Assign'; $buttonTitle = 'Assign'; $buttonColor = '#007bff'; // Blue color } // Get assigned employee names for tooltip $assignedEmployees = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('is_active', true) ->join('employees', 'reseller_ticket_employee_assignments.employee_id', '=', 'employees.id') ->pluck('employees.name') ->toArray(); $assignedUsersText = !empty($assignedEmployees) ? implode(', ', $assignedEmployees) : 'Not Assigned'; @endphp @if(isset($isReseller) && $isReseller) {{ $buttonText }} @else @endif @php // Find who solved the ticket // Check if ticket is solved $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; $solvedByEmployee = null; if ($isSolved) { // Find the employee who had the active assignment when ticket was solved // Get the assignment that was deactivated around the time ticket was resolved $resolvedAt = $ticket->resolved_at ?? ($ticket->closed_at ?? now()); // Find assignment that was active before resolution and deactivated around resolution time $solvedAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('is_active', false) ->whereNotNull('assigned_at') ->orderBy('updated_at', 'desc') ->first(); if ($solvedAssignment) { $solvedEmployee = DB::table('employees') ->where('id', $solvedAssignment->employee_id) ->first(); $solvedByEmployee = $solvedEmployee ? $solvedEmployee->name : null; } // If not found, try to find any employee who had assignment for this ticket if (!$solvedByEmployee) { $anyAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->orderBy('updated_at', 'desc') ->first(); if ($anyAssignment) { $anyEmployee = DB::table('employees') ->where('id', $anyAssignment->employee_id) ->first(); $solvedByEmployee = $anyEmployee ? $anyEmployee->name : null; } } } @endphp @if($isSolved && $solvedByEmployee) {{ $solvedByEmployee }} @elseif($isSolved) N/A @else - @endif @php $createdByUser = $ticket->createdBy; @endphp @if($createdByUser) @if($createdByUser->employeeRecord) {{ $createdByUser->employeeRecord->name ?? $createdByUser->name ?? 'N/A' }} @else {{ $createdByUser->name ?? 'N/A' }} @endif @else N/A @endif @if(!(isset($isReseller) && $isReseller)) @endif @if($isSuperAdmin || $isAdmin || $isEmployee) @if(isset($ticketNotificationCounts[$ticket->id]) && $ticketNotificationCounts[$ticket->id] > 0) {{ $ticketNotificationCounts[$ticket->id] }} @endif @if($ticket->attachments && $ticket->attachments->count() > 0) {{ $ticket->attachments->count() }} @else @endif @php $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; @endphp @if(!$isSolved) @if(isset($employeeMessageNotificationCounts[$ticket->id]) && $employeeMessageNotificationCounts[$ticket->id] > 0) {{ $employeeMessageNotificationCounts[$ticket->id] }} @endif @endif @endif @if(($isSuperAdmin || $isAdmin) && !$isEmployee)
@csrf @method('DELETE')
@endif @php $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; @endphp @if(isset($isReseller) && $isReseller && !$isSolved) @if(isset($resellerMessageNotificationCounts[$ticket->id]) && $resellerMessageNotificationCounts[$ticket->id] > 0) {{ $resellerMessageNotificationCounts[$ticket->id] }} @endif @endif @php $canClose = isset($isReseller) && $isReseller && !$isSolved && $ticket->created_by == auth()->id(); $isIssueStatus = in_array($ticket->status, ['upstream_issues', 'pop_issues', 'transmission_issues']); @endphp @if($canClose)
@csrf @method('POST')
@endif @if(isset($isReseller) && $isReseller && $isIssueStatus) Rate @endif
No tickets found
{{ $tickets->links() }}
@if(isset($isReseller) && $isReseller && isset($solvedTickets) && $solvedTickets->count() > 0)
Solved Tickets ({{ $solvedTickets->total() }})
@if(isset($isReseller) && $isReseller)
SHOW
@if(request('search')) @endif @if(request('status')) @endif @if(request('priority')) @endif @if(request('category_id')) @endif
ENTRIES
@endif
@foreach($solvedTickets as $index => $ticket) @php $slNumber = ($solvedTickets->currentPage() - 1) * $solvedTickets->perPage() + $index + 1; $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; // Find who solved the ticket $solvedByEmployee = null; if ($isSolved) { $resolvedAt = $ticket->resolved_at ?? ($ticket->closed_at ?? now()); $solvedAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('is_active', false) ->whereNotNull('assigned_at') ->orderBy('updated_at', 'desc') ->first(); if ($solvedAssignment) { $solvedEmployee = DB::table('employees') ->where('id', $solvedAssignment->employee_id) ->first(); $solvedByEmployee = $solvedEmployee ? $solvedEmployee->name : null; } if (!$solvedByEmployee) { $anyAssignment = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->orderBy('updated_at', 'desc') ->first(); if ($anyAssignment) { $anyEmployee = DB::table('employees') ->where('id', $anyAssignment->employee_id) ->first(); $solvedByEmployee = $anyEmployee ? $anyEmployee->name : null; } } } // Get assigned employee names $assignedEmployees = DB::table('reseller_ticket_employee_assignments') ->where('reseller_ticket_id', $ticket->id) ->where('is_active', true) ->join('employees', 'reseller_ticket_employee_assignments.employee_id', '=', 'employees.id') ->pluck('employees.name') ->toArray(); $assignedUsersText = !empty($assignedEmployees) ? implode(', ', $assignedEmployees) : 'Not Assigned'; @endphp @endforeach
SL Ticket # Problem Sub Category Priority Rating Assign To Solved by Solved At Actions
{{ $slNumber }} {{ $ticket->ticket_number }} {{ $ticket->category->name ?? ($ticket->description ? Str::limit($ticket->description, 30) : 'N/A') }} {{ $ticket->subcategory->name ?? 'N/A' }} @php $priorityColors = [ 'low' => '#6c757d', 'medium' => '#17a2b8', 'high' => '#ffc107', 'urgent' => '#dc3545' ]; $priorityColor = $priorityColors[$ticket->priority] ?? '#6c757d'; @endphp {{ ucfirst($ticket->priority) }} @if($ticket->rating) @for($i = 1; $i <= 5; $i++) @endfor ({{ $ticket->rating }}/5) @else No rating @endif Solved @if($isSolved && $solvedByEmployee) {{ $solvedByEmployee }} @elseif($isSolved) N/A @else - @endif @if($ticket->resolved_at) {{ \Carbon\Carbon::parse($ticket->resolved_at)->format('Y-m-d H:i:s') }} @elseif($ticket->closed_at) {{ \Carbon\Carbon::parse($ticket->closed_at)->format('Y-m-d H:i:s') }} @else {{ $ticket->updated_at->format('Y-m-d H:i:s') }} @endif @if($isSolved) Rate @endif
{{ $solvedTickets->links() }}
@if(isset($isReseller) && $isReseller && isset($solvedTickets) && $solvedTickets->count() > 0) @foreach($solvedTickets as $ticket) @php $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; @endphp @if($isSolved) @endif @endforeach @endif @if(isset($isReseller) && $isReseller && isset($solvedTickets) && $solvedTickets->count() > 0) @foreach($solvedTickets as $ticket) @php $isSolved = $ticket->resolved_at || $ticket->status === 'resolved' || $ticket->status === 'closed'; @endphp @if($isSolved) @endif @endforeach @endif @elseif(isset($isReseller) && $isReseller && isset($solvedTickets) && $solvedTickets->count() == 0)
Solved Tickets

No solved tickets found.

@endif @foreach($tickets as $ticket) @php // For resellers, exclude 'in_progress' from clickable statuses $clickableStatuses = isset($isReseller) && $isReseller ? ['upstream_issues', 'pop_issues', 'transmission_issues'] : ['in_progress', 'upstream_issues', 'pop_issues', 'transmission_issues']; $shouldShowModal = in_array($ticket->status, $clickableStatuses); @endphp @if($shouldShowModal) @endif @endforeach @foreach($tickets as $ticket) @endforeach @if(isset($isReseller) && $isReseller) @foreach($tickets as $ticket) @endforeach @endif @if($isSuperAdmin || $isAdmin || $isEmployee) @foreach($tickets as $ticket) @endforeach @endif @foreach($tickets as $ticket) @endforeach @if(isset($isReseller) && $isReseller) @foreach($tickets as $ticket) @if($ticket->status === 'resolved' && $ticket->user_id == auth()->id()) @endif @endforeach @endif @if(isset($isReseller) && $isReseller) @foreach($tickets as $ticket) @php $isIssueStatus = in_array($ticket->status, ['upstream_issues', 'pop_issues', 'transmission_issues']); @endphp @if($isIssueStatus) @endif @endforeach @endif @if(isset($isReseller) && $isReseller) @foreach($tickets as $ticket) @php $isIssueStatus = in_array($ticket->status, ['upstream_issues', 'pop_issues', 'transmission_issues']); @endphp @if($isIssueStatus) @endif @endforeach @endif @section('styles') @endsection @endsection @section('scripts') @endsection @push('scripts') @endpush @push('scripts') @endpush