Skip to content

Commit 5789295

Browse files
authored
Merge pull request #61 from mihaisolomon/feature/timesheet-export-data
Timesheet export period filtering
2 parents 2509997 + 0d7dbfa commit 5789295

5 files changed

Lines changed: 192 additions & 9 deletions

File tree

app/Exports/ProjectHoursExport.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use App\Models\Project;
66
use App\Models\Ticket;
77
use App\Models\TicketHour;
8+
use Illuminate\Support\Collection;
89
use Maatwebsite\Excel\Concerns\FromCollection;
910
use Maatwebsite\Excel\Concerns\WithHeadings;
1011

@@ -31,9 +32,9 @@ public function headings(): array
3132
}
3233

3334
/**
34-
* @return \Illuminate\Support\Collection
35+
* @return Collection
3536
*/
36-
public function collection()
37+
public function collection(): Collection
3738
{
3839
$collection = collect();
3940
$this->project->tickets

app/Exports/TimesheetExport.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace App\Exports;
4+
5+
use App\Models\Project;
6+
use App\Models\Ticket;
7+
use App\Models\TicketHour;
8+
use Illuminate\Support\Collection;
9+
use Maatwebsite\Excel\Concerns\FromCollection;
10+
use Maatwebsite\Excel\Concerns\WithHeadings;
11+
12+
class TimesheetExport implements FromCollection, WithHeadings
13+
{
14+
protected array $params;
15+
16+
public function __construct(array $params)
17+
{
18+
$this->params = $params;
19+
}
20+
21+
public function headings(): array
22+
{
23+
return [
24+
'#',
25+
'Project',
26+
'Ticket',
27+
'Details',
28+
'User',
29+
'Time',
30+
'Hours',
31+
'Activity',
32+
'Date',
33+
];
34+
}
35+
36+
/**
37+
* @return Collection
38+
*/
39+
public function collection(): Collection
40+
{
41+
$collection = collect();
42+
43+
$hours = TicketHour::where('user_id', auth()->user()->id)
44+
->whereBetween('created_at', [$this->params['start_date'], $this->params['end_date']])
45+
->get();
46+
47+
foreach ($hours as $item) {
48+
$collection->push([
49+
'#' => $item->ticket->code,
50+
'project' => $item->ticket->project->name,
51+
'ticket' => $item->ticket->name,
52+
'details' => $item->comment,
53+
'user' => $item->user->name,
54+
'time' => $item->forHumans,
55+
'hours' => number_format($item->value, 2, ',', ' '),
56+
'activity' => $item->activity ? $item->activity->name : '-',
57+
'date' => $item->created_at->format(__('Y-m-d g:i A')),
58+
]);
59+
}
60+
61+
return $collection;
62+
}
63+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace App\Filament\Pages;
6+
7+
use Filament\Forms\Components\Card;
8+
use Filament\Forms\Components\Grid;
9+
use Filament\Forms\Concerns\InteractsWithForms;
10+
use Filament\Forms\Contracts\HasForms;
11+
use Filament\Pages\Page;
12+
use Filament\Forms\Components\DatePicker;
13+
use Maatwebsite\Excel\Facades\Excel;
14+
use Symfony\Component\HttpFoundation\BinaryFileResponse;
15+
16+
class TimesheetExport extends Page implements HasForms
17+
{
18+
use InteractsWithForms;
19+
20+
protected static ?string $slug = 'timesheet-export';
21+
22+
protected static ?int $navigationSort = 2;
23+
24+
protected static string $view = 'filament.pages.timesheet-export';
25+
26+
protected static function getNavigationGroup(): ?string
27+
{
28+
return __('Timesheet');
29+
}
30+
31+
public function mount(): void
32+
{
33+
$this->form->fill();
34+
}
35+
36+
protected function getFormSchema(): array
37+
{
38+
return [
39+
Card::make()->schema([
40+
Grid::make()
41+
->columns(2)
42+
->schema([
43+
DatePicker::make('start_date')
44+
->required()
45+
->reactive()
46+
->label('Star date'),
47+
DatePicker::make('end_date')
48+
->required()
49+
->reactive()
50+
->label('End date')
51+
])
52+
])
53+
];
54+
}
55+
56+
public function create(): BinaryFileResponse
57+
{
58+
$data = $this->form->getState();
59+
60+
return Excel::download(
61+
new \App\Exports\TimesheetExport($data),
62+
'time_' . time() . '.csv',
63+
\Maatwebsite\Excel\Excel::CSV,
64+
['Content-Type' => 'text/csv']
65+
);
66+
}
67+
}

app/Filament/Widgets/Timesheet/WeeklyReport.php

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,31 @@ class WeeklyReport extends BarChartWidget
2020
'lg' => 3
2121
];
2222

23-
protected function getData(): array
23+
public function __construct($id = null)
2424
{
25-
$now = Carbon::now();
25+
$weekDaysData = $this->getWeekStartAndFinishDays();
26+
27+
$this->filter = $weekDaysData['weekStartDate'] . ' - ' . $weekDaysData['weekEndDate'];
28+
29+
parent::__construct($id);
30+
}
31+
32+
protected function getHeading(): string
33+
{
34+
return __('Weekly logged time');
35+
}
2636

27-
$weekStartDate = $now->startOfWeek()->format('Y-m-d');
28-
$weekEndDate = $now->endOfWeek()->format('Y-m-d');
37+
protected function getData(): array
38+
{
39+
$weekDaysData = explode(' - ', $this->filter);
2940

3041
$collection = $this->filter(auth()->user(), [
3142
'year' => null,
32-
'weekStartDate' => $weekStartDate,
33-
'weekEndDate' => $weekEndDate
43+
'weekStartDate' => $weekDaysData[0],
44+
'weekEndDate' => $weekDaysData[1]
3445
]);
3546

36-
$dates = $this->buildDatesRange($weekStartDate, $weekEndDate);
47+
$dates = $this->buildDatesRange($weekDaysData[0], $weekDaysData[1]);
3748

3849
$datasets = $this->buildRapport($collection, $dates);
3950

@@ -54,6 +65,11 @@ protected function getData(): array
5465
];
5566
}
5667

68+
protected function getFilters(): ?array
69+
{
70+
return $this->yearWeeks();
71+
}
72+
5773
protected function buildRapport(Collection $collection, array $dates): array
5874
{
5975
$template = $this->createReportTemplate($dates);
@@ -98,4 +114,30 @@ protected function createReportTemplate(array $dates): array
98114
}
99115
return $template;
100116
}
117+
118+
protected function yearWeeks(): array
119+
{
120+
$year = date_create('today')->format('Y');
121+
122+
$dtStart = date_create('2 jan ' . $year)->modify('last Monday');
123+
$dtEnd = date_create('last monday of Dec ' . $year);
124+
125+
for ($weeks = []; $dtStart <= $dtEnd; $dtStart->modify('+1 week')) {
126+
$from = $dtStart->format('Y-m-d');
127+
$to = (clone $dtStart)->modify('+6 Days')->format('Y-m-d');
128+
$weeks[$from . ' - ' . $to] = $from . ' - ' . $to;
129+
}
130+
131+
return $weeks;
132+
}
133+
134+
protected function getWeekStartAndFinishDays(): array
135+
{
136+
$now = Carbon::now();
137+
138+
return [
139+
'weekStartDate' => $now->startOfWeek()->format('Y-m-d'),
140+
'weekEndDate' => $now->endOfWeek()->format('Y-m-d')
141+
];
142+
}
101143
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<x-filament::page>
2+
<div class="w-full flex flex-col gap-10 justify-center items-center">
3+
<form wire:submit.prevent="create" class="lg:w-[50%] w-full">
4+
{{ $this->form }}
5+
<x-filament::button type="submit" form="create" >
6+
{{ __('Create report') }}
7+
</x-filament::button>
8+
</form>
9+
</div>
10+
</x-filament::page>

0 commit comments

Comments
 (0)