@@ -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