Skip to content

Commit 07517c6

Browse files
authored
Merge pull request #31 from eporsche/fix_vacation_allocation
fixed an issue where multiple vacation allowances could not be approved
2 parents 8390089 + 6469816 commit 07517c6

File tree

5 files changed

+181
-6
lines changed

5 files changed

+181
-6
lines changed

.php_cs .php-cs-fixer.php

File renamed without changes.

.styleci.yml

100644100755
File mode changed.

app/Models/VacationEntitlement.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ public function isExpired()
8989
return $this->status === 'expired';
9090
}
9191

92+
public function notExpired()
93+
{
94+
return $this->status != 'expired';
95+
}
96+
9297
public function expire()
9398
{
9499
return $this->update([
@@ -151,15 +156,15 @@ public function useVacationDays(Absence $absence)
151156
return;
152157
}
153158

154-
if ($this->isUsed()) {
159+
if ($this->isUsed() || $this->isExpired()) {
155160
throw ValidationException::withMessages([
156161
'error' => [__('Vacation entitlement has wrong status.')],
157162
]);
158163
}
159164

160-
$this->usedVacationDays()->attach($absence->id, [
165+
tap($this, fn($model) => $model->usedVacationDays()->attach($absence->id, [
161166
'used_days' => $absence->vacation_days
162-
]);
167+
]))->load('usedVacationDays');
163168

164169
if ($this->used_days->isGreaterThanOrEqualTo($this->available_days)) {
165170
$this->markAsUsed();

app/Traits/HasVacations.php

+11-3
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,20 @@ public function availableVacationEntitlements()
2626
public function currentVacationEntitlement()
2727
{
2828
$today = now()->startOfDay();
29-
return $this->availableVacationEntitlements()
29+
$available = $this->availableVacationEntitlements()
3030
->where('starts_at','<=',$today)
3131
->where('ends_at','>=',$today)
3232
->orderBy('ends_at','ASC')
33-
->limit(1)
34-
->first();
33+
->get();
34+
35+
$feasibleEntitlements = $available->filter(function (VacationEntitlement $entitlement) {
36+
if(!$entitlement->isExpired() && !$entitlement->isUsed()) {
37+
return $entitlement;
38+
}
39+
});
40+
41+
return $feasibleEntitlements->first();
42+
3543
}
3644

3745
public function latestVacationEntitlement()

tests/Feature/EvaluationTest.php

+162
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use App\Models\Location;
1313
use App\Models\AbsenceType;
1414
use App\Contracts\AddsAbsences;
15+
use App\Contracts\AddsVacationEntitlements;
1516
use App\Contracts\ApprovesAbsence;
1617
use Illuminate\Support\Facades\Bus;
1718
use App\Contracts\FiltersEvaluation;
@@ -135,6 +136,167 @@ public function test_can_submit_fullday_illness()
135136
//Überstunden
136137

137138
//Urlaub
139+
public function test_can_use_vacation_entitlement()
140+
{
141+
$absenceType = AbsenceType::forceCreate([
142+
'location_id' => $this->location->id,
143+
'title' => 'Urlaub',
144+
'affect_vacation_times' => true,
145+
'affect_evaluations' => true,
146+
'evaluation_calculation_setting' => 'absent_to_target'
147+
]);
148+
149+
$this->user->absenceTypes()->sync($absenceType);
150+
151+
/**
152+
* @var AddsVacationEntitlements
153+
*/
154+
$action = app(AddsVacationEntitlements::class);
155+
$action->add($this->user, [
156+
'name' => "yearly allowance",
157+
'starts_at' => "01.01.2021",
158+
'ends_at' => "31.12.2021",
159+
'days' => 2,
160+
'expires' => false,
161+
'transfer_remaining' => false
162+
]);
163+
164+
/**
165+
* @var AddsAbsences
166+
*/
167+
$action = app(AddsAbsences::class);
168+
$action->add($this->user, $this->location, $this->user->id, [
169+
'absence_type_id' => $absenceType->id,
170+
'starts_at' => '29.11.2021 00:00',
171+
'ends_at' => '30.11.2021 00:00',
172+
'full_day' => true,
173+
'status' => 'confirmed'
174+
]);
175+
176+
Bus::fake();
177+
178+
/**
179+
* @var ApprovesAbsence
180+
*/
181+
$approver = app(ApprovesAbsence::class);
182+
183+
$approver->approve(
184+
$this->user,
185+
$this->location,
186+
Absence::first()->id
187+
);
188+
189+
$this->assertDatabaseHas("absences",[
190+
'id' => Absence::first()->id,
191+
'status' => 'confirmed',
192+
'vacation_days' => 2,
193+
'paid_hours' => 16
194+
]);
195+
196+
$this->assertDatabaseHas("vacation_entitlements",[
197+
'name' => 'yearly allowance',
198+
'status' => 'used',
199+
]);
200+
}
201+
202+
public function test_can_submit_vacation()
203+
{
204+
$absenceType = AbsenceType::forceCreate([
205+
'location_id' => $this->location->id,
206+
'title' => 'Urlaub',
207+
'affect_vacation_times' => true,
208+
'affect_evaluations' => true,
209+
'evaluation_calculation_setting' => 'absent_to_target'
210+
]);
211+
212+
$this->user->absenceTypes()->sync($absenceType);
213+
214+
/**
215+
* @var AddsVacationEntitlements
216+
*/
217+
$action = app(AddsVacationEntitlements::class);
218+
$action->add($this->user, [
219+
'name' => "yearly allowance",
220+
'starts_at' => "01.01.2021",
221+
'ends_at' => "31.12.2021",
222+
'days' => 2,
223+
'expires' => false,
224+
'transfer_remaining' => false
225+
]);
226+
227+
/**
228+
* @var AddsAbsences
229+
*/
230+
$action = app(AddsAbsences::class);
231+
232+
$action->add($this->user, $this->location, $this->user->id, [
233+
'absence_type_id' => $absenceType->id,
234+
'starts_at' => '29.11.2021 00:00',
235+
'ends_at' => '30.11.2021 00:00',
236+
'full_day' => true,
237+
'status' => 'confirmed'
238+
]);
239+
240+
Bus::fake();
241+
242+
/**
243+
* @var ApprovesAbsence
244+
*/
245+
$approver = app(ApprovesAbsence::class);
246+
247+
$approver->approve(
248+
$this->user,
249+
$this->location,
250+
Absence::first()->id
251+
);
252+
253+
$this->assertDatabaseHas("absence_index",[
254+
'date' => '2021-11-29 00:00:00',
255+
'hours' => 8,
256+
]);
257+
258+
$this->assertDatabaseHas("absence_index",[
259+
'date' => '2021-11-30 00:00:00',
260+
'hours' => 8,
261+
]);
262+
263+
/**
264+
* @var AddsVacationEntitlements
265+
*/
266+
$action = app(AddsVacationEntitlements::class);
267+
$action->add($this->user, [
268+
'name' => "additional allowance",
269+
'starts_at' => "01.01.2021",
270+
'ends_at' => "31.12.2021",
271+
'days' => 2,
272+
'expires' => false,
273+
'transfer_remaining' => false
274+
]);
275+
276+
/**
277+
* @var AddsAbsences
278+
*/
279+
$action = app(AddsAbsences::class);
280+
281+
$action->add($this->user, $this->location, $this->user->id, [
282+
'absence_type_id' => $absenceType->id,
283+
'starts_at' => '06.12.2021 00:00',
284+
'ends_at' => '07.12.2021 00:00',
285+
'full_day' => true,
286+
'status' => 'confirmed'
287+
]);
288+
289+
/**
290+
* @var ApprovesAbsence
291+
*/
292+
$approver = app(ApprovesAbsence::class);
293+
294+
$approver->approve(
295+
$this->user,
296+
$this->location,
297+
Absence::where('starts_at','2021-12-06 00:00:00')->first()->id
298+
);
299+
}
138300

139301
//Wunschfrei
140302
}

0 commit comments

Comments
 (0)