Skip to content

Commit

Permalink
#444 - overtime application process (#447)
Browse files Browse the repository at this point in the history
* #444 - wip: added models and create form for overtime requests

* #444 - wip: added full workflow for overtime

* #444 - fixes

* #444 - added tests

* #444 - fix

* #444 - fixes and added policies

* - fixes

* Update app/Enums/SettlementType.php

Co-authored-by: Krzysztof Rewak <[email protected]>

* - cr fixes

* #444 - cr fixes

* #444 - feat: cr fixes, added permissions

* #444 - cr fixes

* #444 - cr fixes

* #444 - cr fixes

* #444 - added more tests

* #444 - fixes connected with caching queries

---------

Co-authored-by: Krzysztof Rewak <[email protected]>
  • Loading branch information
kamilpiech97 and krzysztofrewak authored Jul 4, 2024
1 parent 9966342 commit 2dbcb2e
Show file tree
Hide file tree
Showing 78 changed files with 3,203 additions and 36 deletions.
24 changes: 24 additions & 0 deletions app/Actions/OvertimeRequest/AcceptAsTechnicalAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;

class AcceptAsTechnicalAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
protected ApproveAction $approveAction,
) {}

public function execute(OvertimeRequest $overtimeRequest, User $user): void
{
$this->stateManager->acceptAsTechnical($overtimeRequest, $user);

$this->approveAction->execute($overtimeRequest);
}
}
21 changes: 21 additions & 0 deletions app/Actions/OvertimeRequest/ApproveAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;

class ApproveAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
) {}

public function execute(OvertimeRequest $overtimeRequest, ?User $user = null): void
{
$this->stateManager->approve($overtimeRequest, $user);
}
}
21 changes: 21 additions & 0 deletions app/Actions/OvertimeRequest/CancelAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;

class CancelAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
) {}

public function execute(OvertimeRequest $overtimeRequest, User $user): void
{
$this->stateManager->cancel($overtimeRequest, $user);
}
}
57 changes: 57 additions & 0 deletions app/Actions/OvertimeRequest/CreateAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Illuminate\Validation\ValidationException;
use Toby\Domain\OvertimeCalculator;
use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;
use Toby\Validation\OvertimeRequestValidator;

class CreateAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
protected WaitForTechApprovalAction $waitForTechApprovalAction,
protected OvertimeCalculator $overtimeCalculator,
protected OvertimeRequestValidator $overtimeRequestValidator,
) {}

/**
* @throws ValidationException
*/
public function execute(array $data, User $creator): OvertimeRequest
{
$overtimeRequest = $this->createVacationRequest($data, $creator);

$this->handleCreatedOvertimeRequest($overtimeRequest);

return $overtimeRequest;
}

/**
* @throws ValidationException
*/
protected function createVacationRequest(array $data, User $creator): OvertimeRequest
{
/** @var OvertimeRequest $overtimeRequest */
$overtimeRequest = $creator->createdOvertimeRequests()->make($data);
$overtimeRequest->hours = $this->overtimeCalculator->calculateHours($overtimeRequest->from, $overtimeRequest->to);

$this->overtimeRequestValidator->validate($overtimeRequest);

$overtimeRequest->save();

$this->stateManager->markAsCreated($overtimeRequest);

return $overtimeRequest;
}

protected function handleCreatedOvertimeRequest(OvertimeRequest $overtimeRequest): void
{
$this->waitForTechApprovalAction->execute($overtimeRequest);
}
}
21 changes: 21 additions & 0 deletions app/Actions/OvertimeRequest/RejectAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;

class RejectAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
) {}

public function execute(OvertimeRequest $overtimeRequest, User $user): void
{
$this->stateManager->reject($overtimeRequest, $user);
}
}
21 changes: 21 additions & 0 deletions app/Actions/OvertimeRequest/SettleAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;

class SettleAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
) {}

public function execute(OvertimeRequest $overtimeRequest, User $user): void
{
$this->stateManager->settle($overtimeRequest, $user);
}
}
22 changes: 22 additions & 0 deletions app/Actions/OvertimeRequest/WaitForTechApprovalAction.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Toby\Actions\OvertimeRequest;

use Toby\Actions\VacationRequest\ApproveAction;
use Toby\Domain\OvertimeRequestStateManager;
use Toby\Models\OvertimeRequest;

class WaitForTechApprovalAction
{
public function __construct(
protected OvertimeRequestStateManager $stateManager,
protected ApproveAction $approveAction,
) {}

public function execute(OvertimeRequest $overtimeRequest): void
{
$this->stateManager->waitForTechnical($overtimeRequest);
}
}
6 changes: 2 additions & 4 deletions app/Domain/DashboardAggregator.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public function aggregateCalendarData(User $user, YearPeriod $yearPeriod): array
->vacations()
->with(["vacationRequest.vacations", "vacationRequest.user.profile"])
->whereBelongsTo($yearPeriod)
->cache()
->cache("vacations{$user->id}")
->approved()
->get()
->mapWithKeys(
Expand All @@ -64,7 +64,7 @@ public function aggregateCalendarData(User $user, YearPeriod $yearPeriod): array
->vacations()
->with(["vacationRequest.vacations", "vacationRequest.user.profile"])
->whereBelongsTo($yearPeriod)
->cache()
->cache("vacations{$user->id}")
->pending()
->get()
->mapWithKeys(
Expand Down Expand Up @@ -92,15 +92,13 @@ public function aggregateVacationRequests(User $user, YearPeriod $yearPeriod): J
->states(VacationRequestStatesRetriever::waitingForUserActionStates($user))
->latest("updated_at")
->limit(3)
->cache()
->get();
} else {
$vacationRequests = $user->vacationRequests()
->with(["user", "vacations", "vacations.user", "vacations.user.profile", "user.permissions", "user.profile"])
->whereBelongsTo($yearPeriod)
->latest("updated_at")
->limit(3)
->cache()
->get();
}

Expand Down
18 changes: 18 additions & 0 deletions app/Domain/OvertimeCalculator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace Toby\Domain;

use Carbon\Carbon;
use Carbon\CarbonInterface;

class OvertimeCalculator
{
public function calculateHours(CarbonInterface $from, CarbonInterface $to): int
{
$hours = Carbon::create($from)->diffInMinutes($to);

return (int)ceil($hours / 60);
}
}
80 changes: 80 additions & 0 deletions app/Domain/OvertimeRequestStateManager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<?php

declare(strict_types=1);

namespace Toby\Domain;

use Illuminate\Contracts\Events\Dispatcher;
use Toby\Models\OvertimeRequest;
use Toby\Models\User;
use Toby\States\OvertimeRequest\AcceptedByTechnical;
use Toby\States\OvertimeRequest\Approved;
use Toby\States\OvertimeRequest\Cancelled;
use Toby\States\OvertimeRequest\OvertimeRequestState;
use Toby\States\OvertimeRequest\Rejected;
use Toby\States\OvertimeRequest\Settled;
use Toby\States\OvertimeRequest\WaitingForTechnical;

class OvertimeRequestStateManager
{
public function __construct(
protected Dispatcher $dispatcher,
) {}

public function markAsCreated(OvertimeRequest $overtimeRequest): void
{
$this->createActivity($overtimeRequest, null, $overtimeRequest->state, $overtimeRequest->creator);
}

public function approve(OvertimeRequest $overtimeRequest, ?User $user = null): void
{
$this->changeState($overtimeRequest, Approved::class, $user);
}

public function reject(OvertimeRequest $overtimeRequest, User $user): void
{
$this->changeState($overtimeRequest, Rejected::class, $user);
}

public function cancel(OvertimeRequest $overtimeRequest, User $user): void
{
$this->changeState($overtimeRequest, Cancelled::class, $user);
}

public function acceptAsTechnical(OvertimeRequest $overtimeRequest, User $user): void
{
$this->changeState($overtimeRequest, AcceptedByTechnical::class, $user);
}

public function waitForTechnical(OvertimeRequest $overtimeRequest): void
{
$this->changeState($overtimeRequest, WaitingForTechnical::class);
}

public function settle(OvertimeRequest $overtimeRequest, User $user): void
{
$this->changeState($overtimeRequest, Settled::class, $user);
}

protected function changeState(OvertimeRequest $overtimeRequest, string $state, ?User $user = null): void
{
$previousState = $overtimeRequest->state;
$overtimeRequest->state->transitionTo($state);
$overtimeRequest->save();

$this->createActivity($overtimeRequest, $previousState, $overtimeRequest->state, $user);
}

protected function createActivity(
OvertimeRequest $overtimeRequest,
?OvertimeRequestState $from,
OvertimeRequestState $to,
?User $user = null,
): void {
$overtimeRequest->activities()->create([
"from" => $from,
"to" => $to,
"user_id" => $user?->id,
]);
}
}
Loading

0 comments on commit 2dbcb2e

Please sign in to comment.