Skip to content

Commit b8110e2

Browse files
committed
Fixed descriptions and billable in shared reports
1 parent 7673b36 commit b8110e2

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed

app/Service/TimeEntryAggregationService.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,20 @@ private function loadDescriptorsMap(array $keys, TimeEntryAggregationType $type)
280280
'color' => null,
281281
];
282282
}
283+
} elseif ($type === TimeEntryAggregationType::Description) {
284+
foreach ($keys as $key) {
285+
$descriptorMap[$key] = [
286+
'description' => $key,
287+
'color' => null,
288+
];
289+
}
290+
} elseif ($type === TimeEntryAggregationType::Billable) {
291+
foreach ($keys as $key) {
292+
$descriptorMap[$key] = [
293+
'description' => $key === '0' ? 'Non-billable' : 'Billable',
294+
'color' => null,
295+
];
296+
}
283297
}
284298

285299
return $descriptorMap;

tests/Unit/Service/TimeEntryAggregationServiceTest.php

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,198 @@ public function test_aggregate_time_entries_by_client_and_project_with_filled_ga
498498
],
499499
], $result);
500500
}
501+
502+
public function test_aggregated_time_entries_with_descriptions_by_description_and_billable(): void
503+
{
504+
// Arrange
505+
TimeEntry::factory()->startWithDuration(now(), 10)->create([
506+
'description' => 'TEST 1',
507+
'billable' => true,
508+
]);
509+
TimeEntry::factory()->startWithDuration(now(), 10)->create([
510+
'description' => '',
511+
'billable' => false,
512+
]);
513+
TimeEntry::factory()->startWithDuration(now(), 10)->create([
514+
'description' => 'TEST 1',
515+
'billable' => false,
516+
]);
517+
TimeEntry::factory()->startWithDuration(now(), 10)->create([
518+
'description' => '',
519+
'billable' => false,
520+
]);
521+
$query = TimeEntry::query();
522+
523+
// Act
524+
$result = $this->service->getAggregatedTimeEntriesWithDescriptions(
525+
$query,
526+
TimeEntryAggregationType::Description,
527+
TimeEntryAggregationType::Billable,
528+
'Europe/Vienna',
529+
Weekday::Monday,
530+
false,
531+
null,
532+
null,
533+
true
534+
);
535+
536+
// Assert
537+
$this->assertSame([
538+
'seconds' => 40,
539+
'cost' => 0,
540+
'grouped_type' => 'description',
541+
'grouped_data' => [
542+
[
543+
'key' => null,
544+
'seconds' => 20,
545+
'cost' => 0,
546+
'grouped_type' => 'billable',
547+
'grouped_data' => [
548+
[
549+
'key' => '0',
550+
'seconds' => 20,
551+
'cost' => 0,
552+
'grouped_type' => null,
553+
'grouped_data' => null,
554+
'description' => 'Non-billable',
555+
'color' => null,
556+
],
557+
],
558+
'description' => null,
559+
'color' => null,
560+
],
561+
[
562+
'key' => 'TEST 1',
563+
'seconds' => 20,
564+
'cost' => 0,
565+
'grouped_type' => 'billable',
566+
'grouped_data' => [
567+
[
568+
'key' => '0',
569+
'seconds' => 10,
570+
'cost' => 0,
571+
'grouped_type' => null,
572+
'grouped_data' => null,
573+
'description' => 'Non-billable',
574+
'color' => null,
575+
],
576+
[
577+
'key' => '1',
578+
'seconds' => 10,
579+
'cost' => 0,
580+
'grouped_type' => null,
581+
'grouped_data' => null,
582+
'description' => 'Billable',
583+
'color' => null,
584+
],
585+
],
586+
'description' => 'TEST 1',
587+
'color' => null,
588+
],
589+
],
590+
], $result);
591+
}
592+
593+
public function test_aggregated_time_entries_with_descriptions_by_client_and_project(): void
594+
{
595+
// Arrange
596+
$client1 = Client::factory()->create();
597+
$client2 = Client::factory()->create();
598+
$project1 = Project::factory()->forClient($client1)->create();
599+
$project2 = Project::factory()->forClient($client2)->create();
600+
$project3 = Project::factory()->create();
601+
TimeEntry::factory()->startWithDuration(now(), 10)->forProject($project1)->create();
602+
TimeEntry::factory()->startWithDuration(now(), 10)->forProject($project2)->create();
603+
TimeEntry::factory()->startWithDuration(now(), 10)->forProject($project3)->create();
604+
TimeEntry::factory()->startWithDuration(now(), 10)->create();
605+
$query = TimeEntry::query();
606+
607+
// Act
608+
$result = $this->service->getAggregatedTimeEntriesWithDescriptions(
609+
$query,
610+
TimeEntryAggregationType::Client,
611+
TimeEntryAggregationType::Project,
612+
'Europe/Vienna',
613+
Weekday::Monday,
614+
false,
615+
null,
616+
null,
617+
true
618+
);
619+
620+
// Assert
621+
$this->assertEqualsCanonicalizing([
622+
'seconds' => 40,
623+
'cost' => 0,
624+
'grouped_type' => 'client',
625+
'grouped_data' => [
626+
[
627+
'key' => null,
628+
'seconds' => 20,
629+
'cost' => 0,
630+
'grouped_type' => 'project',
631+
'grouped_data' => [
632+
[
633+
'key' => null,
634+
'seconds' => 10,
635+
'cost' => 0,
636+
'grouped_type' => null,
637+
'grouped_data' => null,
638+
'description' => null,
639+
'color' => null,
640+
],
641+
[
642+
'key' => $project3->getKey(),
643+
'seconds' => 10,
644+
'cost' => 0,
645+
'grouped_type' => null,
646+
'grouped_data' => null,
647+
'description' => $project3->name,
648+
'color' => $project3->color,
649+
],
650+
],
651+
'description' => null,
652+
'color' => null,
653+
],
654+
[
655+
'key' => $client1->getKey(),
656+
'seconds' => 10,
657+
'cost' => 0,
658+
'grouped_type' => 'project',
659+
'grouped_data' => [
660+
[
661+
'key' => $project1->getKey(),
662+
'seconds' => 10,
663+
'cost' => 0,
664+
'grouped_type' => null,
665+
'grouped_data' => null,
666+
'description' => $project1->name,
667+
'color' => $project1->color,
668+
],
669+
],
670+
'description' => $client1->name,
671+
'color' => null,
672+
],
673+
[
674+
'key' => $client2->getKey(),
675+
'seconds' => 10,
676+
'cost' => 0,
677+
'grouped_type' => 'project',
678+
'grouped_data' => [
679+
[
680+
'key' => $project2->getKey(),
681+
'seconds' => 10,
682+
'cost' => 0,
683+
'grouped_type' => null,
684+
'grouped_data' => null,
685+
'description' => $project2->name,
686+
'color' => $project2->color,
687+
],
688+
],
689+
'description' => $client2->name,
690+
'color' => null,
691+
],
692+
],
693+
], $result);
694+
}
501695
}

0 commit comments

Comments
 (0)