- Implemented dashboard view with vehicle stats, active services, recent activity, and upcoming appointments. - Created estimates view with filtering options and a list of service estimates. - Developed invoices view to manage service invoices and payment history with filtering. - Added vehicles view to display registered vehicles and their details. - Built work orders view to track the progress of vehicle services with filtering and detailed information.
206 lines
6.4 KiB
PHP
206 lines
6.4 KiB
PHP
<?php
|
|
|
|
namespace App\Livewire\Timesheets;
|
|
|
|
use App\Models\Timesheet;
|
|
use App\Models\JobCard;
|
|
use Livewire\Component;
|
|
use Livewire\WithPagination;
|
|
use Livewire\Attributes\Validate;
|
|
|
|
class Index extends Component
|
|
{
|
|
use WithPagination;
|
|
|
|
// Filter properties
|
|
public $selectedTechnician = '';
|
|
public $dateFrom = '';
|
|
public $dateTo = '';
|
|
public $selectedStatus = '';
|
|
|
|
// Modal properties
|
|
public $showCreateModal = false;
|
|
public $showEditModal = false;
|
|
public $editingTimesheetId = null;
|
|
|
|
// Form properties
|
|
public $form = [
|
|
'user_id' => '',
|
|
'job_card_id' => '',
|
|
'date' => '',
|
|
'start_time' => '',
|
|
'end_time' => '',
|
|
'description' => '',
|
|
];
|
|
|
|
public function mount()
|
|
{
|
|
$this->dateFrom = now()->startOfMonth()->format('Y-m-d');
|
|
$this->dateTo = now()->format('Y-m-d');
|
|
$this->form['date'] = now()->format('Y-m-d');
|
|
}
|
|
|
|
public function updatingSelectedTechnician()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingDateFrom()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingDateTo()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function updatingSelectedStatus()
|
|
{
|
|
$this->resetPage();
|
|
}
|
|
|
|
public function createTimesheet()
|
|
{
|
|
$this->validate([
|
|
'form.user_id' => 'required|exists:users,id',
|
|
'form.date' => 'required|date',
|
|
'form.start_time' => 'required',
|
|
'form.end_time' => 'nullable|after:form.start_time',
|
|
'form.description' => 'nullable|string|max:1000',
|
|
]);
|
|
|
|
$timesheet = new Timesheet();
|
|
$timesheet->user_id = $this->form['user_id'];
|
|
$timesheet->job_card_id = $this->form['job_card_id'] ?: null;
|
|
$timesheet->date = $this->form['date'];
|
|
$timesheet->start_time = $this->form['date'] . ' ' . $this->form['start_time'];
|
|
|
|
if ($this->form['end_time']) {
|
|
$timesheet->end_time = $this->form['date'] . ' ' . $this->form['end_time'];
|
|
$timesheet->hours_worked = $this->calculateHours($this->form['start_time'], $this->form['end_time']);
|
|
$timesheet->status = 'completed';
|
|
} else {
|
|
$timesheet->status = 'active';
|
|
$timesheet->hours_worked = 0;
|
|
}
|
|
|
|
$timesheet->description = $this->form['description'];
|
|
$timesheet->save();
|
|
|
|
$this->closeModal();
|
|
session()->flash('message', 'Timesheet entry created successfully.');
|
|
}
|
|
|
|
public function editTimesheet($id)
|
|
{
|
|
$timesheet = Timesheet::findOrFail($id);
|
|
$this->editingTimesheetId = $id;
|
|
$this->form = [
|
|
'user_id' => $timesheet->user_id,
|
|
'job_card_id' => $timesheet->job_card_id,
|
|
'date' => $timesheet->date->format('Y-m-d'),
|
|
'start_time' => $timesheet->start_time ? $timesheet->start_time->format('H:i') : '',
|
|
'end_time' => $timesheet->end_time ? $timesheet->end_time->format('H:i') : '',
|
|
'description' => $timesheet->description,
|
|
];
|
|
$this->showEditModal = true;
|
|
}
|
|
|
|
public function updateTimesheet()
|
|
{
|
|
$this->validate([
|
|
'form.user_id' => 'required|exists:users,id',
|
|
'form.date' => 'required|date',
|
|
'form.start_time' => 'required',
|
|
'form.end_time' => 'nullable|after:form.start_time',
|
|
'form.description' => 'nullable|string|max:1000',
|
|
]);
|
|
|
|
$timesheet = Timesheet::findOrFail($this->editingTimesheetId);
|
|
$timesheet->user_id = $this->form['user_id'];
|
|
$timesheet->job_card_id = $this->form['job_card_id'] ?: null;
|
|
$timesheet->date = $this->form['date'];
|
|
$timesheet->start_time = $this->form['date'] . ' ' . $this->form['start_time'];
|
|
|
|
if ($this->form['end_time']) {
|
|
$timesheet->end_time = $this->form['date'] . ' ' . $this->form['end_time'];
|
|
$timesheet->hours_worked = $this->calculateHours($this->form['start_time'], $this->form['end_time']);
|
|
$timesheet->status = 'submitted';
|
|
} else {
|
|
$timesheet->end_time = null;
|
|
$timesheet->status = 'draft';
|
|
$timesheet->hours_worked = 0;
|
|
}
|
|
|
|
$timesheet->description = $this->form['description'];
|
|
$timesheet->save();
|
|
|
|
$this->closeModal();
|
|
session()->flash('message', 'Timesheet entry updated successfully.');
|
|
}
|
|
|
|
public function deleteTimesheet($id)
|
|
{
|
|
Timesheet::findOrFail($id)->delete();
|
|
session()->flash('message', 'Timesheet entry deleted successfully.');
|
|
}
|
|
|
|
public function closeModal()
|
|
{
|
|
$this->showCreateModal = false;
|
|
$this->showEditModal = false;
|
|
$this->editingTimesheetId = null;
|
|
$this->form = [
|
|
'user_id' => '',
|
|
'job_card_id' => '',
|
|
'date' => now()->format('Y-m-d'),
|
|
'start_time' => '',
|
|
'end_time' => '',
|
|
'description' => '',
|
|
];
|
|
}
|
|
|
|
private function calculateHours($startTime, $endTime)
|
|
{
|
|
$start = \Carbon\Carbon::createFromFormat('H:i', $startTime);
|
|
$end = \Carbon\Carbon::createFromFormat('H:i', $endTime);
|
|
return $end->diffInHours($start, true);
|
|
}
|
|
|
|
public function render()
|
|
{
|
|
$timesheets = Timesheet::with([
|
|
'user',
|
|
'jobCard.customer',
|
|
'jobCard.vehicle'
|
|
])
|
|
->when($this->selectedTechnician, function ($query) {
|
|
$query->where('user_id', $this->selectedTechnician);
|
|
})
|
|
->when($this->dateFrom, function ($query) {
|
|
$query->whereDate('date', '>=', $this->dateFrom);
|
|
})
|
|
->when($this->dateTo, function ($query) {
|
|
$query->whereDate('date', '<=', $this->dateTo);
|
|
})
|
|
->when($this->selectedStatus, function ($query) {
|
|
$query->where('status', $this->selectedStatus);
|
|
})
|
|
->latest('date')
|
|
->paginate(15);
|
|
|
|
$technicians = \App\Models\User::where('role', 'technician')
|
|
->orWhere('role', 'admin')
|
|
->orderBy('name')
|
|
->get();
|
|
$jobCards = JobCard::with('vehicle', 'customer')
|
|
->where('status', '!=', 'completed')
|
|
->latest()
|
|
->limit(50)
|
|
->get();
|
|
|
|
return view('livewire.timesheets.index', compact('timesheets', 'technicians', 'jobCards'));
|
|
}
|
|
}
|