802 lines
32 KiB
PHP
802 lines
32 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Work;
|
|
use App\Models\User;
|
|
use App\Models\Transaction;
|
|
use App\Models\Dealer;
|
|
use App\Models\Role;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class TechnicianReportService
|
|
{
|
|
/**
|
|
* Get technician report data for all works and mechanics on a specific date range
|
|
*/
|
|
public function getTechnicianReportData($dealerId = null, $startDate = null, $endDate = null)
|
|
{
|
|
try {
|
|
// Get current authenticated user
|
|
$user = auth()->user();
|
|
|
|
if (!$user) {
|
|
return [
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
];
|
|
}
|
|
|
|
// Validate dealer access
|
|
if ($dealerId) {
|
|
if ($user->dealer_id) {
|
|
// User has specific dealer_id, check if they can access the requested dealer
|
|
if ($user->dealer_id != $dealerId) {
|
|
if ($user->role_id) {
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if (!$role || !$role->hasDealer($dealerId)) {
|
|
// User doesn't have access to this dealer
|
|
return [
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
];
|
|
}
|
|
} else {
|
|
// User has dealer_id but no role, can only access their dealer
|
|
return [
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
];
|
|
}
|
|
}
|
|
} else if ($user->role_id) {
|
|
// User has role, check if they can access the requested dealer
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if (!$role || !$role->hasDealer($dealerId)) {
|
|
// User doesn't have access to this dealer
|
|
return [
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
];
|
|
}
|
|
}
|
|
}
|
|
|
|
Log::info('Getting technician report data', [
|
|
'user_id' => $user->id,
|
|
'dealer_id' => $dealerId,
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate
|
|
]);
|
|
|
|
// Get all works with category in single query
|
|
$works = Work::with(['category'])
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
// Get mechanics based on dealer and role access
|
|
$mechanics = $this->getMechanicsByDealer($dealerId);
|
|
|
|
Log::info('Mechanics found for report:', [
|
|
'count' => $mechanics->count(),
|
|
'dealer_id_filter' => $dealerId,
|
|
'mechanics' => $mechanics->map(function($mechanic) {
|
|
$roleName = 'Unknown';
|
|
if ($mechanic->role) {
|
|
$roleName = is_string($mechanic->role) ? $mechanic->role : $mechanic->role->name;
|
|
}
|
|
return [
|
|
'id' => $mechanic->id,
|
|
'name' => $mechanic->name,
|
|
'role_id' => $mechanic->role_id,
|
|
'role_name' => $roleName,
|
|
'dealer_id' => $mechanic->dealer_id
|
|
];
|
|
})
|
|
]);
|
|
|
|
// Get all transaction data in single optimized query
|
|
$transactions = $this->getOptimizedTransactionData($dealerId, $startDate, $endDate, $mechanics->pluck('id'), $works->pluck('id'));
|
|
|
|
Log::info('Transaction data:', [
|
|
'transaction_count' => count($transactions),
|
|
'sample_transactions' => array_slice($transactions, 0, 5, true),
|
|
'dealer_id_filter' => $dealerId,
|
|
'is_admin_with_pivot' => $user->role_id ? (function() use ($user) {
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
return $role && $this->isAdminRole($role) && $role->dealers->count() > 0;
|
|
})() : false
|
|
]);
|
|
|
|
$data = [];
|
|
|
|
foreach ($works as $work) {
|
|
$row = [
|
|
'work_id' => $work->id,
|
|
'work_name' => $work->name,
|
|
'work_code' => $work->shortname,
|
|
'category_name' => $work->category ? $work->category->name : '-',
|
|
'total_tickets' => 0
|
|
];
|
|
|
|
// Calculate totals for each mechanic
|
|
foreach ($mechanics as $mechanic) {
|
|
$key = $work->id . '_' . $mechanic->id;
|
|
$mechanicData = $transactions[$key] ?? ['total' => 0, 'completed' => 0, 'pending' => 0];
|
|
|
|
$row["mechanic_{$mechanic->id}_total"] = $mechanicData['total'];
|
|
|
|
// Add to totals
|
|
$row['total_tickets'] += $mechanicData['total'];
|
|
}
|
|
|
|
$data[] = $row;
|
|
}
|
|
|
|
Log::info('Final data prepared:', [
|
|
'data_count' => count($data),
|
|
'sample_data' => array_slice($data, 0, 2)
|
|
]);
|
|
|
|
return [
|
|
'data' => $data,
|
|
'mechanics' => $mechanics,
|
|
'works' => $works
|
|
];
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Error in getTechnicianReportData: ' . $e->getMessage(), [
|
|
'dealer_id' => $dealerId,
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate,
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
// Return empty data structure but with proper format
|
|
return [
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get optimized transaction data in single query
|
|
*/
|
|
private function getOptimizedTransactionData($dealerId = null, $startDate = null, $endDate = null, $mechanicIds = null, $workIds = null)
|
|
{
|
|
// Get current authenticated user
|
|
$user = auth()->user();
|
|
|
|
if (!$user) {
|
|
return [];
|
|
}
|
|
|
|
// Validate dealer access
|
|
if ($dealerId) {
|
|
if ($user->dealer_id) {
|
|
// User has specific dealer_id, check if they can access the requested dealer
|
|
if ($user->dealer_id != $dealerId) {
|
|
if ($user->role_id) {
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if (!$role || !$role->hasDealer($dealerId)) {
|
|
// User doesn't have access to this dealer
|
|
return [];
|
|
}
|
|
} else {
|
|
// User has dealer_id but no role, can only access their dealer
|
|
return [];
|
|
}
|
|
}
|
|
} else if ($user->role_id) {
|
|
// User has role, check if they can access the requested dealer
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if (!$role || !$role->hasDealer($dealerId)) {
|
|
// User doesn't have access to this dealer
|
|
return [];
|
|
}
|
|
}
|
|
}
|
|
|
|
Log::info('Getting optimized transaction data', [
|
|
'user_id' => $user->id,
|
|
'dealer_id' => $dealerId,
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate
|
|
]);
|
|
|
|
$query = Transaction::select(
|
|
'work_id',
|
|
'user_id',
|
|
'status',
|
|
DB::raw('COUNT(*) as count')
|
|
)
|
|
->groupBy('work_id', 'user_id', 'status');
|
|
|
|
if ($dealerId) {
|
|
$query->where('dealer_id', $dealerId);
|
|
} else if ($user->role_id) {
|
|
// Check if admin with pivot dealers and "Semua Dealer" selected
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if ($role && $this->isAdminRole($role) && $role->dealers->count() > 0) {
|
|
// Admin with pivot dealers and "Semua Dealer" selected - filter by pivot dealers
|
|
$accessibleDealerIds = $role->dealers->pluck('id');
|
|
$query->whereIn('dealer_id', $accessibleDealerIds);
|
|
Log::info('Admin with pivot dealers, filtering transactions by pivot dealer IDs:', $accessibleDealerIds->toArray());
|
|
}
|
|
}
|
|
|
|
if ($startDate) {
|
|
$query->where('date', '>=', $startDate);
|
|
}
|
|
|
|
if ($endDate) {
|
|
$query->where('date', '<=', $endDate);
|
|
}
|
|
|
|
if ($mechanicIds && $mechanicIds->count() > 0) {
|
|
$query->whereIn('user_id', $mechanicIds);
|
|
}
|
|
|
|
if ($workIds && $workIds->count() > 0) {
|
|
$query->whereIn('work_id', $workIds);
|
|
}
|
|
|
|
// Remove index hint that doesn't exist
|
|
$results = $query->get();
|
|
|
|
Log::info('Transaction query results', [
|
|
'results_count' => $results->count()
|
|
]);
|
|
|
|
// Organize data by work_id_user_id key
|
|
$organizedData = [];
|
|
|
|
foreach ($results as $result) {
|
|
$key = $result->work_id . '_' . $result->user_id;
|
|
|
|
if (!isset($organizedData[$key])) {
|
|
$organizedData[$key] = [
|
|
'total' => 0,
|
|
'completed' => 0,
|
|
'pending' => 0
|
|
];
|
|
}
|
|
|
|
$organizedData[$key]['total'] += $result->count;
|
|
|
|
if ($result->status == 1) {
|
|
$organizedData[$key]['completed'] += $result->count;
|
|
} else {
|
|
$organizedData[$key]['pending'] += $result->count;
|
|
}
|
|
}
|
|
|
|
return $organizedData;
|
|
}
|
|
|
|
/**
|
|
* Get total ticket count for a specific work and mechanic (legacy method for backward compatibility)
|
|
*/
|
|
private function getTicketCount($workId, $mechanicId, $dealerId = null, $startDate = null, $endDate = null)
|
|
{
|
|
$query = Transaction::where('work_id', $workId)
|
|
->where('user_id', $mechanicId);
|
|
|
|
if ($dealerId) {
|
|
$query->where('dealer_id', $dealerId);
|
|
}
|
|
|
|
if ($startDate) {
|
|
$query->where('date', '>=', $startDate);
|
|
}
|
|
|
|
if ($endDate) {
|
|
$query->where('date', '<=', $endDate);
|
|
}
|
|
|
|
return $query->count();
|
|
}
|
|
|
|
/**
|
|
* Get completed ticket count for a specific work and mechanic (legacy method for backward compatibility)
|
|
*/
|
|
private function getCompletedTicketCount($workId, $mechanicId, $dealerId = null, $startDate = null, $endDate = null)
|
|
{
|
|
$query = Transaction::where('work_id', $workId)
|
|
->where('user_id', $mechanicId)
|
|
->where('status', 1); // Assuming status 1 is completed
|
|
|
|
if ($dealerId) {
|
|
$query->where('dealer_id', $dealerId);
|
|
}
|
|
|
|
if ($startDate) {
|
|
$query->where('date', '>=', $startDate);
|
|
}
|
|
|
|
if ($endDate) {
|
|
$query->where('date', '<=', $endDate);
|
|
}
|
|
|
|
return $query->count();
|
|
}
|
|
|
|
/**
|
|
* Get pending ticket count for a specific work and mechanic (legacy method for backward compatibility)
|
|
*/
|
|
private function getPendingTicketCount($workId, $mechanicId, $dealerId = null, $startDate = null, $endDate = null)
|
|
{
|
|
$query = Transaction::where('work_id', $workId)
|
|
->where('user_id', $mechanicId)
|
|
->where('status', 0); // Assuming status 0 is pending
|
|
|
|
if ($dealerId) {
|
|
$query->where('dealer_id', $dealerId);
|
|
}
|
|
|
|
if ($startDate) {
|
|
$query->where('date', '>=', $startDate);
|
|
}
|
|
|
|
if ($endDate) {
|
|
$query->where('date', '<=', $endDate);
|
|
}
|
|
|
|
return $query->count();
|
|
}
|
|
|
|
/**
|
|
* Get all dealers for filter
|
|
*/
|
|
public function getDealers()
|
|
{
|
|
// Get current authenticated user
|
|
$user = auth()->user();
|
|
|
|
if (!$user) {
|
|
Log::info('No authenticated user found');
|
|
return collect();
|
|
}
|
|
|
|
Log::info('Getting dealers for user:', [
|
|
'user_id' => $user->id,
|
|
'user_name' => $user->name,
|
|
'user_role_id' => $user->role_id,
|
|
'user_dealer_id' => $user->dealer_id
|
|
]);
|
|
|
|
// If user has role, check role type and dealer access
|
|
if ($user->role_id) {
|
|
$role = Role::with(['dealers' => function($query) {
|
|
$query->whereNull('dealers.deleted_at'); // Only active dealers
|
|
}])->find($user->role_id);
|
|
|
|
Log::info('Role details:', [
|
|
'role_id' => $role ? $role->id : null,
|
|
'role_name' => $role ? $role->name : null,
|
|
'role_dealers_count' => $role ? $role->dealers->count() : 0,
|
|
'role_dealers' => $role ? $role->dealers->pluck('id', 'name')->toArray() : []
|
|
]);
|
|
|
|
if ($role) {
|
|
// Check if role is admin type
|
|
if ($this->isAdminRole($role)) {
|
|
// Admin role - check if has pivot dealers
|
|
if ($role->dealers->count() > 0) {
|
|
// Admin with pivot dealers - return pivot dealers (for "Semua Dealer" option)
|
|
Log::info('Admin role with pivot dealers, returning pivot dealers');
|
|
$dealers = $role->dealers()->whereNull('dealers.deleted_at')->orderBy('name')->get(['dealers.id', 'dealers.name', 'dealers.dealer_code']);
|
|
Log::info('Returning pivot dealers for admin:', $dealers->toArray());
|
|
return $dealers;
|
|
} else {
|
|
// Admin without pivot dealers - return all dealers
|
|
Log::info('Admin role without pivot dealers, returning all dealers');
|
|
$allDealers = Dealer::whereNull('deleted_at')->orderBy('name')->get(['id', 'name', 'dealer_code']);
|
|
Log::info('Returning all dealers for admin:', $allDealers->toArray());
|
|
return $allDealers;
|
|
}
|
|
}
|
|
|
|
// Role has dealer relationship (tampilkan dealer berdasarkan pivot)
|
|
if ($role->dealers->count() > 0) {
|
|
Log::info('Role has dealers relationship, returning role dealers');
|
|
$dealers = $role->dealers()->whereNull('dealers.deleted_at')->orderBy('name')->get(['dealers.id', 'dealers.name', 'dealers.dealer_code']);
|
|
Log::info('Returning dealers from role:', $dealers->toArray());
|
|
return $dealers;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If user has specific dealer_id but no role dealers, check if they can access their dealer_id
|
|
if ($user->dealer_id) {
|
|
Log::info('User has specific dealer_id:', ['dealer_id' => $user->dealer_id]);
|
|
if ($user->role_id) {
|
|
$role = Role::with(['dealers' => function($query) {
|
|
$query->whereNull('dealers.deleted_at'); // Only active dealers
|
|
}])->find($user->role_id);
|
|
|
|
if ($role && $role->hasDealer($user->dealer_id)) {
|
|
Log::info('User can access their dealer_id, returning single dealer');
|
|
$dealer = Dealer::where('id', $user->dealer_id)->whereNull('deleted_at')->orderBy('name')->get(['id', 'name', 'dealer_code']);
|
|
Log::info('Returning dealer:', $dealer->toArray());
|
|
return $dealer;
|
|
} else {
|
|
Log::info('User cannot access their dealer_id');
|
|
}
|
|
}
|
|
Log::info('User has dealer_id but no role or no access, returning empty');
|
|
return collect();
|
|
}
|
|
|
|
// Fallback: return all dealers if no restrictions
|
|
Log::info('No restrictions found, returning all dealers');
|
|
$allDealers = Dealer::whereNull('deleted_at')->orderBy('name')->get(['id', 'name', 'dealer_code']);
|
|
Log::info('Returning all dealers:', $allDealers->toArray());
|
|
return $allDealers;
|
|
}
|
|
|
|
/**
|
|
* Check if role is admin type (should show all dealers)
|
|
*/
|
|
public function isAdminRole($role)
|
|
{
|
|
// Define admin role names that should have access to all dealers
|
|
$adminRoleNames = [
|
|
'admin',
|
|
'super admin',
|
|
'administrator',
|
|
'sa',
|
|
'superadmin'
|
|
];
|
|
|
|
// Check if role name contains admin keywords (but not "area")
|
|
$roleName = strtolower(trim($role->name));
|
|
foreach ($adminRoleNames as $adminName) {
|
|
if (strpos($roleName, $adminName) !== false && strpos($roleName, 'area') === false) {
|
|
Log::info('Role identified as admin type:', ['role_name' => $role->name]);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
// Check if role has no dealer restrictions (no pivot relationships)
|
|
// This means role can access all dealers
|
|
if ($role->dealers->count() === 0) {
|
|
Log::info('Role has no dealer restrictions, treating as admin type:', ['role_name' => $role->name]);
|
|
return true;
|
|
}
|
|
|
|
// Role with "area" in name should use pivot dealers, not all dealers
|
|
if (strpos($roleName, 'area') !== false) {
|
|
Log::info('Role contains "area", treating as area role (use pivot dealers):', ['role_name' => $role->name]);
|
|
return false;
|
|
}
|
|
|
|
Log::info('Role is not admin type:', ['role_name' => $role->name]);
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get default dealer for filter (berbasis user role)
|
|
*/
|
|
public function getDefaultDealer()
|
|
{
|
|
// Get current authenticated user
|
|
$user = auth()->user();
|
|
|
|
if (!$user) {
|
|
return null;
|
|
}
|
|
|
|
Log::info('Getting default dealer for user:', [
|
|
'user_id' => $user->id,
|
|
'user_role_id' => $user->role_id,
|
|
'user_dealer_id' => $user->dealer_id
|
|
]);
|
|
|
|
// If user has role, check role type and dealer access
|
|
if ($user->role_id) {
|
|
$role = Role::with(['dealers' => function($query) {
|
|
$query->whereNull('dealers.deleted_at'); // Only active dealers
|
|
}])->find($user->role_id);
|
|
|
|
if ($role) {
|
|
// Check if role is admin type
|
|
if ($this->isAdminRole($role)) {
|
|
// Admin role - check if has pivot dealers
|
|
if ($role->dealers->count() > 0) {
|
|
// Admin with pivot dealers - return first dealer from pivot
|
|
Log::info('Admin role with pivot dealers, returning first dealer from pivot');
|
|
$defaultDealer = $role->dealers()->whereNull('dealers.deleted_at')->orderBy('name')->first();
|
|
Log::info('Default dealer for admin with pivot:', $defaultDealer ? $defaultDealer->toArray() : null);
|
|
return $defaultDealer;
|
|
} else {
|
|
// Admin without pivot dealers - no default dealer (show all dealers without selection)
|
|
Log::info('Admin role without pivot dealers, no default dealer');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// Role has dealer relationship (return first dealer from role dealers)
|
|
if ($role->dealers->count() > 0) {
|
|
Log::info('Role has dealers relationship, returning first dealer from role dealers');
|
|
$defaultDealer = $role->dealers()->whereNull('dealers.deleted_at')->orderBy('name')->first();
|
|
Log::info('Default dealer from role dealers:', $defaultDealer ? $defaultDealer->toArray() : null);
|
|
return $defaultDealer;
|
|
}
|
|
}
|
|
}
|
|
|
|
// If user has specific dealer_id, check if they can access it
|
|
if ($user->dealer_id) {
|
|
if ($user->role_id) {
|
|
$role = Role::with(['dealers' => function($query) {
|
|
$query->whereNull('dealers.deleted_at'); // Only active dealers
|
|
}])->find($user->role_id);
|
|
if ($role && $role->hasDealer($user->dealer_id)) {
|
|
$defaultDealer = Dealer::where('id', $user->dealer_id)->whereNull('deleted_at')->first();
|
|
Log::info('User dealer found:', $defaultDealer ? $defaultDealer->toArray() : null);
|
|
return $defaultDealer;
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Fallback: no default dealer
|
|
Log::info('No default dealer found');
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Get mechanics for a specific dealer
|
|
*/
|
|
public function getMechanicsByDealer($dealerId = null)
|
|
{
|
|
// Get current authenticated user
|
|
$user = auth()->user();
|
|
|
|
if (!$user) {
|
|
return collect();
|
|
}
|
|
|
|
Log::info('Getting mechanics by dealer:', [
|
|
'user_id' => $user->id,
|
|
'user_role_id' => $user->role_id,
|
|
'user_dealer_id' => $user->dealer_id,
|
|
'requested_dealer_id' => $dealerId
|
|
]);
|
|
|
|
$query = User::with('role')->whereHas('role', function($query) {
|
|
$query->where('name', 'mechanic');
|
|
});
|
|
|
|
// If user has role, check role type and dealer access
|
|
if ($user->role_id) {
|
|
$role = Role::with(['dealers' => function($query) {
|
|
$query->whereNull('dealers.deleted_at'); // Only active dealers
|
|
}])->find($user->role_id);
|
|
|
|
if ($role) {
|
|
// Check if role is admin type
|
|
if ($this->isAdminRole($role)) {
|
|
// Admin role - check if has pivot dealers
|
|
if ($role->dealers->count() > 0) {
|
|
// Admin with pivot dealers
|
|
if ($dealerId) {
|
|
// Specific dealer selected - get mechanics from that dealer
|
|
Log::info('Admin with pivot dealers, specific dealer selected:', ['dealer_id' => $dealerId]);
|
|
$query->where('dealer_id', $dealerId);
|
|
} else {
|
|
// "Semua Dealer" selected - get mechanics from all pivot dealers
|
|
Log::info('Admin with pivot dealers, "Semua Dealer" selected, getting mechanics from all pivot dealers');
|
|
$accessibleDealerIds = $role->dealers->pluck('id');
|
|
$query->whereIn('dealer_id', $accessibleDealerIds);
|
|
Log::info('Accessible dealer IDs for admin:', $accessibleDealerIds->toArray());
|
|
}
|
|
} else {
|
|
// Admin without pivot dealers - can access all dealers
|
|
Log::info('Admin without pivot dealers, can access mechanics from all dealers');
|
|
if ($dealerId) {
|
|
$query->where('dealer_id', $dealerId);
|
|
}
|
|
// If no dealer_id, show all mechanics (no additional filtering)
|
|
}
|
|
} else {
|
|
// Role has dealer relationship (filter by accessible dealers)
|
|
if ($role->dealers->count() > 0) {
|
|
Log::info('Role has dealers relationship, filtering mechanics by accessible dealers');
|
|
$accessibleDealerIds = $role->dealers->pluck('id');
|
|
$query->whereIn('dealer_id', $accessibleDealerIds);
|
|
Log::info('Accessible dealer IDs:', $accessibleDealerIds->toArray());
|
|
} else {
|
|
Log::info('Role has no dealers, returning empty');
|
|
return collect();
|
|
}
|
|
}
|
|
}
|
|
} else if ($user->dealer_id) {
|
|
// User has specific dealer_id but no role, can only access their dealer
|
|
Log::info('User has dealer_id but no role, can only access their dealer');
|
|
$query->where('dealer_id', $user->dealer_id);
|
|
}
|
|
|
|
// Apply dealer filter if provided (for non-admin roles)
|
|
if ($dealerId && !$this->isAdminRole($role ?? null)) {
|
|
Log::info('Applying dealer filter for non-admin role:', ['dealer_id' => $dealerId]);
|
|
$query->where('dealer_id', $dealerId);
|
|
}
|
|
|
|
$mechanics = $query->orderBy('name')->get(['id', 'name', 'dealer_id']);
|
|
|
|
Log::info('Mechanics found:', [
|
|
'count' => $mechanics->count(),
|
|
'mechanics' => $mechanics->map(function($mechanic) {
|
|
return [
|
|
'id' => $mechanic->id,
|
|
'name' => $mechanic->name,
|
|
'dealer_id' => $mechanic->dealer_id
|
|
];
|
|
})->toArray()
|
|
]);
|
|
|
|
return $mechanics;
|
|
}
|
|
|
|
/**
|
|
* Get technician report data for Yajra DataTable
|
|
*/
|
|
public function getTechnicianReportDataForDataTable($dealerId = null, $startDate = null, $endDate = null)
|
|
{
|
|
try {
|
|
// Get current authenticated user
|
|
$user = auth()->user();
|
|
|
|
if (!$user) {
|
|
return response()->json([
|
|
'draw' => request()->input('draw', 1),
|
|
'recordsTotal' => 0,
|
|
'recordsFiltered' => 0,
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
]);
|
|
}
|
|
|
|
// Validate dealer access
|
|
if ($dealerId) {
|
|
if ($user->dealer_id) {
|
|
// User has specific dealer_id, check if they can access the requested dealer
|
|
if ($user->dealer_id != $dealerId) {
|
|
if ($user->role_id) {
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if (!$role || !$role->hasDealer($dealerId)) {
|
|
// User doesn't have access to this dealer
|
|
return response()->json([
|
|
'draw' => request()->input('draw', 1),
|
|
'recordsTotal' => 0,
|
|
'recordsFiltered' => 0,
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
]);
|
|
}
|
|
} else {
|
|
// User has dealer_id but no role, can only access their dealer
|
|
return response()->json([
|
|
'draw' => request()->input('draw', 1),
|
|
'recordsTotal' => 0,
|
|
'recordsFiltered' => 0,
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
]);
|
|
}
|
|
}
|
|
} else if ($user->role_id) {
|
|
// User has role, check if they can access the requested dealer
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
if (!$role || !$role->hasDealer($dealerId)) {
|
|
// User doesn't have access to this dealer
|
|
return response()->json([
|
|
'draw' => request()->input('draw', 1),
|
|
'recordsTotal' => 0,
|
|
'recordsFiltered' => 0,
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
]);
|
|
}
|
|
}
|
|
}
|
|
|
|
Log::info('Getting technician report data for DataTable', [
|
|
'user_id' => $user->id,
|
|
'dealer_id' => $dealerId,
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate
|
|
]);
|
|
|
|
// Get all works with category
|
|
$works = Work::with(['category'])
|
|
->orderBy('name')
|
|
->get();
|
|
|
|
// Get mechanics based on dealer and role access
|
|
$mechanics = $this->getMechanicsByDealer($dealerId);
|
|
|
|
// Get transaction data
|
|
$transactions = $this->getOptimizedTransactionData($dealerId, $startDate, $endDate, $mechanics->pluck('id'), $works->pluck('id'));
|
|
|
|
Log::info('Transaction data for DataTable:', [
|
|
'transaction_count' => count($transactions),
|
|
'dealer_id_filter' => $dealerId,
|
|
'is_admin_with_pivot' => $user->role_id ? (function() use ($user) {
|
|
$role = Role::with('dealers')->find($user->role_id);
|
|
return $role && $this->isAdminRole($role) && $role->dealers->count() > 0;
|
|
})() : false
|
|
]);
|
|
|
|
$data = [];
|
|
|
|
foreach ($works as $work) {
|
|
$row = [
|
|
'DT_RowIndex' => count($data) + 1,
|
|
'work_name' => $work->name,
|
|
'work_code' => $work->shortname,
|
|
'category_name' => $work->category ? $work->category->name : '-'
|
|
];
|
|
|
|
// Add mechanic columns
|
|
foreach ($mechanics as $mechanic) {
|
|
$key = $work->id . '_' . $mechanic->id;
|
|
$mechanicData = $transactions[$key] ?? ['total' => 0, 'completed' => 0, 'pending' => 0];
|
|
|
|
$row["mechanic_{$mechanic->id}_total"] = $mechanicData['total'];
|
|
}
|
|
|
|
$data[] = $row;
|
|
}
|
|
|
|
Log::info('DataTable response prepared', [
|
|
'data_count' => count($data),
|
|
'mechanics_count' => $mechanics->count(),
|
|
'works_count' => $works->count()
|
|
]);
|
|
|
|
// Create DataTable response
|
|
return response()->json([
|
|
'draw' => request()->input('draw', 1),
|
|
'recordsTotal' => count($data),
|
|
'recordsFiltered' => count($data),
|
|
'data' => $data,
|
|
'mechanics' => $mechanics,
|
|
'works' => $works
|
|
]);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Error in getTechnicianReportDataForDataTable: ' . $e->getMessage(), [
|
|
'dealer_id' => $dealerId,
|
|
'start_date' => $startDate,
|
|
'end_date' => $endDate,
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
return response()->json([
|
|
'draw' => request()->input('draw', 1),
|
|
'recordsTotal' => 0,
|
|
'recordsFiltered' => 0,
|
|
'data' => [],
|
|
'mechanics' => collect(),
|
|
'works' => collect()
|
|
]);
|
|
}
|
|
}
|
|
|
|
}
|