• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ericfortmeyer / activity-log / 20488915339

24 Dec 2025 03:11PM UTC coverage: 49.13% (-2.7%) from 51.874%
20488915339

push

github

web-flow
fix: add support for emailing reports (#62)

Fixes #9

Signed-off-by: Eric Fortmeyer <e.fortmeyer01@gmail.com>

72 of 224 new or added lines in 12 files covered. (32.14%)

5 existing lines in 3 files now uncovered.

339 of 690 relevant lines covered (49.13%)

1.52 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

60.0
/src/Http/RequestProcessors/GetTimeEntries.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace EricFortmeyer\ActivityLog\Http\RequestProcessors;
6

7
use Phpolar\Phpolar\Auth\{
8
    Authorize
9
};
10
use Phpolar\{
11
    Model\Model,
12
    Storage\NotFound
13
};
14
use EricFortmeyer\ActivityLog\{RemarksForMonth, MonthFilters, CreditHours, Tenant, TimeEntry};
15
use EricFortmeyer\ActivityLog\Services\{
16
    RemarksForMonthService,
17
    CreditHoursService,
18
    TemplateBinder,
19
    TenantService,
20
    TimeEntryService
21
};
22
use EricFortmeyer\ActivityLog\UserInterface\Contexts\{TimeEntriesContext, BadRequestContext};
23
use EricFortmeyer\ActivityLog\Utils\Hasher;
24

25
/**
26
 * Class GetTimeEntries
27
 *
28
 * @package EricFortmeyer\ActivityLog
29
 */
30
final class GetTimeEntries extends AbstractTenantBasedRequestProcessor
31
{
32
    public function __construct(
33
        private readonly TenantService $tenantService,
34
        private readonly TimeEntryService $timeEntryService,
35
        private readonly RemarksForMonthService $remarksForMonthService,
36
        private readonly CreditHoursService $creditHoursService,
37
        private readonly TemplateBinder $templateEngine,
38
        readonly Hasher $hasher,
39
    ) {
40
        parent::__construct($hasher);
2✔
41
    }
42

43
    /**
44
     * Process the request to get all time entries.
45
     *
46
     * @return string The rendered template
47
     */
48
    #[Authorize]
49
    public function process(
50
        #[Model] TimeEntry $timeEntry = new TimeEntry(),
51
        #[Model] MonthFilters $monthFilters = new MonthFilters(),
52
    ): string {
53
        if ($monthFilters->isValid() === false) {
2✔
NEW
54
            return $this->templateEngine->apply(
×
55
                "400",
×
NEW
56
                new BadRequestContext(message: "Something is wrong with the request.")
×
57
            );
×
58
        }
59

60
        $this->initTenantIfNotExists();
2✔
61

62
        $timeEntry->tenantId ??= $this->getTenantId();
2✔
63
        $month = $monthFilters->getMonth();
2✔
64
        $year = $monthFilters->getYear();
2✔
65
        TimeEntry::setUninitializedValues(timeEntry: $timeEntry, month: $month, year: $year);
2✔
66
        $timeEntries = $this->timeEntryService->getAllByMonth(
2✔
67
            month: $month,
2✔
68
            year: $year,
2✔
69
            tenantId: $this->getTenantId(),
2✔
70
        );
2✔
71
        $remarks = $this->remarksForMonthService->get(RemarksForMonth::getIdFromMonth(
2✔
72
            month: $month,
2✔
73
            year: $year,
2✔
74
            tenantId: $this->getTenantId(),
2✔
75
        ));
2✔
76
        $creditHours = $this->creditHoursService->get(CreditHours::getIdFromMonth(
2✔
77
            month: $month,
2✔
78
            year: $year,
2✔
79
            tenantId: $this->getTenantId(),
2✔
80
        ));
2✔
81
        return $this->templateEngine->apply(
2✔
82
            "index",
2✔
83
            match (true) {
2✔
84
                $remarks instanceof NotFound && $creditHours instanceof NotFound =>
2✔
85
                new TimeEntriesContext(
2✔
86
                    timeEntries: $timeEntries,
2✔
87
                    tenantId: $this->getTenantId(),
2✔
88
                    currentEntry: $timeEntry,
2✔
89
                    filters: $monthFilters,
2✔
90
                    user: $this->user
2✔
91
                ),
2✔
92
                $creditHours instanceof CreditHours && $remarks instanceof RemarksForMonth =>
2✔
NEW
93
                new TimeEntriesContext(
×
UNCOV
94
                    timeEntries: $timeEntries,
×
NEW
95
                    tenantId: $this->getTenantId(),
×
NEW
96
                    currentEntry: $timeEntry,
×
NEW
97
                    filters: $monthFilters,
×
UNCOV
98
                    remarks: $remarks,
×
UNCOV
99
                    creditHours: $creditHours,
×
NEW
100
                    user: $this->user
×
NEW
101
                ),
×
102
                $creditHours instanceof CreditHours && $remarks instanceof NotFound =>
2✔
NEW
103
                new TimeEntriesContext(
×
NEW
104
                    timeEntries: $timeEntries,
×
NEW
105
                    tenantId: $this->getTenantId(),
×
NEW
106
                    currentEntry: $timeEntry,
×
NEW
107
                    filters: $monthFilters,
×
NEW
108
                    creditHours: $creditHours,
×
NEW
109
                    user: $this->user,
×
NEW
110
                ),
×
111
                $remarks instanceof RemarksForMonth && $creditHours instanceof NotFound =>
2✔
NEW
112
                new TimeEntriesContext(
×
NEW
113
                    timeEntries: $timeEntries,
×
NEW
114
                    tenantId: $this->getTenantId(),
×
NEW
115
                    currentEntry: $timeEntry,
×
NEW
116
                    filters: $monthFilters,
×
NEW
117
                    remarks: $remarks,
×
NEW
118
                    user: $this->user
×
NEW
119
                ),
×
120
                default =>
2✔
121
                new TimeEntriesContext(user: $this->user, tenantId: $this->getTenantId())
2✔
122
            }
2✔
123
        );
2✔
124
    }
125

126
    private function initTenantIfNotExists(): void
127
    {
128
        $tenantId = $this->getTenantId();
2✔
129

130
        if ($this->tenantService->exists($tenantId) === true) {
2✔
131
            return;
×
132
        }
133

134
        $this->tenantService->save(
2✔
135
            new Tenant(["id" => $tenantId])
2✔
136
        );
2✔
137
    }
138
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc