Commit 9f0cfc11 authored by Jacob Priddy's avatar Jacob Priddy 👌

Revert "Make attempts and entries use shallow linking by location"

This reverts commit 95157362.
parent 8b358f2e
Pipeline #12518 passed with stages
in 2 minutes and 25 seconds
......@@ -3,8 +3,17 @@
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Attempt extends Model
{
protected $fillable = ['door_location'];
protected $fillable = ['door_id'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function door(): BelongsTo
{
return $this->belongsTo(Door::class);
}
}
......@@ -20,6 +20,22 @@ class Door extends Authenticatable
return $this->belongsToMany(Group::class);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function entries(): HasMany
{
return $this->hasMany(Entry::class);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function attempts(): HasMany
{
return $this->hasMany(Attempt::class);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
......@@ -36,6 +52,18 @@ class Door extends Authenticatable
// Detach all groups
$door->groups()->detach();
// Delete all entries
/** @var \App\Entry $entry */
foreach ($door->entries() as $entry) {
$entry->delete();
}
// Delete all attempts
/** @var \App\Attempt $attempt */
foreach ($door->attempts() as $attempt) {
$attempt->delete();
}
// Delete all overrides
/** @var \App\Override $override */
foreach ($door->overrides() as $override) {
......
......@@ -7,7 +7,15 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Entry extends Model
{
protected $fillable = ['door_location', 'user_id', 'success'];
protected $fillable = ['door_id', 'user_id', 'success'];
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function door(): BelongsTo
{
return $this->belongsTo(Door::class);
}
/**
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
......
......@@ -17,7 +17,7 @@ class AttemptsController extends ApiController
/**
* Get Attempts
*
* This route filters attempts based off of starting date, ending date, or door location.
* This route filters attempts based off of starting date, ending date, or door id.
* If only start is supplied, all attempts after the start date are given. If only end
* is supplied, all attempts before the start date are given. If both dates are supplied,
* all attempts between the given dates are returned. This route is paginated.
......@@ -26,9 +26,9 @@ class AttemptsController extends ApiController
* @paginated
* @queryParam start The beginning date to filter attempts by. Example: 2000-06-02 08:11:45
* @queryParam end The ending date to filter attempts by. Example: 2920-06-02 08:11:45
* @queryParam door_location The door location to filter on. Example: The Amazon
* @queryParam door_id The door id to filter on. Example: 1
*
* @response 422 {"message":"The given data was invalid.","errors":{"start":["The start is not a valid date."],"end":["The end is not a valid date."],"door_location":["The door location must be a string."]}}
* @response 422 {"message":"The given data was invalid.","errors":{"start":["The start is not a valid date."],"end":["The end is not a valid date."],"door_id":["The door id must be an integer."]}}
*
* @param \Source\UseCases\Attempts\GetAttempts\GetAttemptsUseCase $attempts
* @return \Illuminate\Http\JsonResponse
......@@ -44,7 +44,7 @@ class AttemptsController extends ApiController
$this->validate($this->request, [
'start' => 'nullable|date',
'end' => 'nullable|date',
'door_location' => 'nullable|string',
'door_id' => 'nullable|integer',
]);
$presenter = new GetAttemptsAPIPresenter();
......@@ -52,7 +52,7 @@ class AttemptsController extends ApiController
$attempts->getBetweenDates(
$this->request->input('start'),
$this->request->input('end'),
$this->request->input('door_location'),
$this->request->input('door_id'),
$presenter
);
......
......@@ -25,10 +25,10 @@ class EntriesController extends ApiController
* @paginated
* @queryParam start The beginning date to filter entries by. Example: 2000-06-02 08:11:45
* @queryParam end The ending date to filter entries by. Example: 2920-06-02 08:11:45
* @queryParam door_id The door id to filter entries on. Example: Amazon
* @queryParam door_id The door id to filter entries on. Example: 1
* @queryParam user_id The user id to filter entries on. Example: 420
*
* @response 422 {"message":"The given data was invalid.","errors":{"start":["The start is not a valid date."],"end":["The end is not a valid date."],"door_location":["The door location must be a string."],"user_id":["The user id must be an integer."]}}
* @response 422 {"message":"The given data was invalid.","errors":{"start":["The start is not a valid date."],"end":["The end is not a valid date."],"door_id":["The door id must be an integer."],"user_id":["The user id must be an integer."]}}
*
* @param \Source\UseCases\Entries\GetEntries\GetEntriesUseCase $userEntries
* @return \Illuminate\Http\JsonResponse
......@@ -43,7 +43,7 @@ class EntriesController extends ApiController
$this->validate($this->request, [
'start' => 'nullable|date',
'end' => 'nullable|date',
'door_location' => 'nullable|string',
'door_id' => 'nullable|integer',
'user_id' => 'nullable|integer',
]);
......@@ -51,7 +51,7 @@ class EntriesController extends ApiController
$userEntries->getEntries(
$this->request->input('user_id'),
$this->request->input('door_location'),
$this->request->input('door_id'),
$this->request->input('start'),
$this->request->input('end'),
$presenter
......
......@@ -14,14 +14,13 @@ class AttemptsController extends Controller
* @param \Source\UseCases\Attempts\GetAttempts\GetAttemptsUseCase $attempts
* @return \Illuminate\View\View
* @throws \Illuminate\Validation\ValidationException
* @throws \Exception
*/
public function index(GetAttemptsUseCase $attempts): View
{
$this->validate($this->request, [
'start' => 'nullable|date',
'end' => 'nullable|date',
'door_location' => 'nullable|string',
'door_id' => 'nullable|integer',
]);
$start = $this->request->input('start');
......
......@@ -22,7 +22,7 @@ class EntriesController extends Controller
$this->validate($this->request, [
'start' => 'nullable|date',
'end' => 'nullable|date',
'door_location' => 'nullable|string',
'door_id' => 'nullable|integer',
'user_id' => 'nullable|integer',
]);
......@@ -38,7 +38,7 @@ class EntriesController extends Controller
$entries->getEntries(
$this->request->input('user_id'),
$this->request->input('door_location'),
$this->request->input('door_id'),
$start,
$end,
$presenter
......
......@@ -17,8 +17,9 @@ class CreateEntriesTable extends Migration
Schema::create('entries', static function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id');
$table->string('door_location');
$table->unsignedBigInteger('door_id');
$table->boolean('success');
$table->foreign('door_id')->references('id')->on('doors');
$table->foreign('user_id')->references('id')->on('users');
$table->timestamps();
});
......
......@@ -15,7 +15,8 @@ class CreateAttemptsTable extends Migration
{
Schema::create('attempts', static function (Blueprint $table) {
$table->id();
$table->string('door_location');
$table->unsignedBigInteger('door_id');
$table->foreign('door_id')->references('id')->on('doors');
$table->timestamps();
});
}
......
......@@ -38,12 +38,6 @@
{{ door($row[$header])['name'] }} (ID: {{ $row[$header] }})
</a>
</td>
@elseif($header === 'door_shallow_link')
<td>
<a href="{{ route('web.admin.doors.index', ['query' => $row[$header]]) }}">
{{ $row[$header] }}
</a>
</td>
@elseif($header === 'schedule_id')
<td>
<a href="{{ route('web.admin.schedules.edit', ['scheduleId' => $row[$header]]) }}">
......
......@@ -15,7 +15,7 @@ class Attempt
/**
* @var int
*/
protected string $doorLocation;
protected int $doorId;
/**
* @var \Carbon\Carbon|null
......@@ -29,12 +29,12 @@ class Attempt
public function __construct(
int $id,
string $doorLocation,
int $doorId,
?Carbon $createdAt = null,
?Carbon $updatedAt = null
) {
$this->id = $id;
$this->doorLocation = $doorLocation;
$this->doorId = $doorId;
$this->createdAt = $createdAt;
$this->updatedAt = $updatedAt;
}
......@@ -48,11 +48,11 @@ class Attempt
}
/**
* @return string
* @return int
*/
public function getDoorLocation(): string
public function getDoorId(): int
{
return $this->doorLocation;
return $this->doorId;
}
/**
......@@ -94,15 +94,15 @@ class Attempt
}
/**
* @param string|null $doorLocation
* @param string|null $doorId
* @return bool
*/
public function hasDoorLocationLike(?string $doorLocation): bool
public function hasDoorIdOf(?string $doorId): bool
{
if (!$doorLocation) {
if (!$doorId) {
return false;
}
return stripos($this->getDoorLocation(), $doorLocation) !== false;
return $this->getDoorId() === (int)$doorId;
}
}
......@@ -18,9 +18,9 @@ class Entry
protected int $userId;
/**
* @var string
* @var int
*/
protected string $doorLocation;
protected int $doorId;
/**
* @var \Carbon\Carbon|null
......@@ -40,14 +40,14 @@ class Entry
public function __construct(
int $id,
int $userId,
string $doorLocation,
int $doorId,
bool $success,
?Carbon $createdAt = null,
?Carbon $updatedAt = null
) {
$this->id = $id;
$this->userId = $userId;
$this->doorLocation = $doorLocation;
$this->doorId = $doorId;
$this->success = $success;
$this->createdAt = $createdAt;
$this->updatedAt = $updatedAt;
......@@ -70,11 +70,11 @@ class Entry
}
/**
* @return string
* @return int
*/
public function getDoorLocation(): string
public function getDoorId(): int
{
return $this->doorLocation;
return $this->doorId;
}
/**
......@@ -141,15 +141,15 @@ class Entry
}
/**
* @param string|null $doorLocation
* @param string|null $doorId
* @return bool
*/
public function hasDoorLocationLike(?string $doorLocation): bool
public function hasDoorIdOf(?string $doorId): bool
{
if (!$doorLocation) {
if (!$doorId) {
return false;
}
return stripos($this->getDoorLocation(), $doorLocation) !== false;
return $this->getDoorId() === (int)$doorId;
}
}
......@@ -17,8 +17,8 @@ interface AttemptsRepository
/**
* @param \Carbon\Carbon|null $begin
* @param \Carbon\Carbon|null $end
* @param string|null $doorLocation
* @param string|null $doorId
* @return \Source\Entities\Attempt[]
*/
public function getBetween(?Carbon $begin = null, ?Carbon $end = null, ?string $doorLocation = null): array;
public function getBetween(?Carbon $begin = null, ?Carbon $end = null, ?string $doorId = null): array;
}
......@@ -19,7 +19,7 @@ class DatabaseAttemptsRepository implements AttemptsRepository
{
return new Attempt(
$attempt->getAttribute('id'),
$attempt->getAttribute('door_location'),
$attempt->getAttribute('door_id'),
$attempt->getAttribute('created_at'),
$attempt->getAttribute('updated_at')
);
......@@ -28,12 +28,12 @@ class DatabaseAttemptsRepository implements AttemptsRepository
/**
* @inheritDoc
*/
public function getBetween(?Carbon $begin = null, ?Carbon $end = null, ?string $doorLocation = null): array
public function getBetween(?Carbon $begin = null, ?Carbon $end = null, ?string $doorId = null): array
{
$query = \App\Attempt::query()->orderByDesc('created_at');
if ($doorLocation) {
$query->where('door_location', 'ILIKE', "%$doorLocation%");
if ($doorId) {
$query->where('door_id', self::castToInt($doorId));
}
if ($begin && $end) {
......@@ -55,7 +55,7 @@ class DatabaseAttemptsRepository implements AttemptsRepository
public function add(Attempt $attempt): ?Attempt
{
$a = new \App\Attempt();
$a->setAttribute('door_location', $attempt->getDoorLocation());
$a->setAttribute('door_id', $attempt->getDoorId());
$a->save();
......
......@@ -34,11 +34,11 @@ class InMemoryAttemptsRepository implements AttemptsRepository
/**
* @inheritDoc
*/
public function getBetween(?Carbon $begin = null, ?Carbon $end = null, ?string $doorLocation = null): array
public function getBetween(?Carbon $begin = null, ?Carbon $end = null, ?string $doorId = null): array
{
return array_values(array_filter($this->attempts, static function (Attempt $attempt) use ($begin, $end, $doorLocation) {
if ($doorLocation) {
return $attempt->isBetween($begin, $end) && $attempt->hasDoorLocationLike($doorLocation);
return array_values(array_filter($this->attempts, static function (Attempt $attempt) use ($begin, $end, $doorId) {
if ($doorId) {
return $attempt->isBetween($begin, $end) && $attempt->hasDoorIdOf($doorId);
}
return $attempt->isBetween($begin, $end);
}));
......
......@@ -13,13 +13,13 @@ class LocalAttemptsRepository extends InMemoryAttemptsRepository
{
$this->add(new Attempt(
1,
LocalDoorsRepository::getTheBatCave()->getLocation(),
LocalDoorsRepository::getTheBatCave()->getId(),
Carbon::now()->subHour()
));
$this->add(new Attempt(
2,
LocalDoorsRepository::getAmazonDoor()->getLocation(),
LocalDoorsRepository::getAmazonDoor()->getId(),
Carbon::now()->subDays(10)
));
}
......
......@@ -20,7 +20,7 @@ class DatabaseEntriesRepository implements EntriesRepository
return new Entry(
$entry->getAttribute('id'),
$entry->getAttribute('user_id'),
$entry->getAttribute('door_location'),
$entry->getAttribute('door_id'),
$entry->getAttribute('success'),
$entry->getAttribute('created_at'),
$entry->getAttribute('updated_at')
......@@ -34,7 +34,7 @@ class DatabaseEntriesRepository implements EntriesRepository
{
$e = new \App\Entry();
$e->setAttribute('user_id', $entry->getUserId());
$e->setAttribute('door_location', $entry->getDoorLocation());
$e->setAttribute('door_id', $entry->getDoorId());
$e->setAttribute('success', $entry->wasSuccessful());
if (!$e->save()) {
......@@ -47,7 +47,7 @@ class DatabaseEntriesRepository implements EntriesRepository
/**
* @inheritDoc
*/
public function get(?Carbon $begin = null, ?Carbon $end = null, ?string $userId = null, ?string $doorLocation = null): array
public function get(?Carbon $begin = null, ?Carbon $end = null, ?string $userId = null, ?string $doorId = null): array
{
$query = \App\Entry::query()->orderByDesc('created_at');
......@@ -55,8 +55,8 @@ class DatabaseEntriesRepository implements EntriesRepository
$query->where('user_id', self::castToInt($userId));
}
if ($doorLocation) {
$query->where('door_location', 'ILIKE', "%$doorLocation%");
if ($doorId) {
$query->where('door_id', self::castToInt($doorId));
}
if ($begin && $end) {
......
......@@ -20,13 +20,13 @@ interface EntriesRepository
* @param \Carbon\Carbon|null $begin
* @param \Carbon\Carbon|null $end
* @param string|null $userId
* @param string|null $doorLocation
* @param string|null $doorId
* @return array
*/
public function get(
?Carbon $begin = null,
?Carbon $end = null,
?string $userId = null,
?string $doorLocation = null
?string $doorId = null
): array;
}
......@@ -34,17 +34,17 @@ class InMemoryEntriesRepository implements EntriesRepository
/**
* @inheritDoc
*/
public function get(?Carbon $begin = null, ?Carbon $end = null, ?string $userId = null, ?string $doorLocation = null): array
public function get(?Carbon $begin = null, ?Carbon $end = null, ?string $userId = null, ?string $doorId = null): array
{
return array_values(array_filter($this->entries, static function (Entry $entry) use ($begin, $end, $userId, $doorLocation) {
return array_values(array_filter($this->entries, static function (Entry $entry) use ($begin, $end, $userId, $doorId) {
$include = $entry->isBetween($begin, $end);
if ($userId) {
$include = $include && $entry->hasUserIdOf($userId);
}
if ($doorLocation) {
$include = $include && $entry->hasDoorLocationLike($doorLocation);
if ($doorId) {
$include = $include && $entry->hasDoorIdOf($doorId);
}
return $include;
......
......@@ -18,7 +18,7 @@ class LocalEntriesRepository extends InMemoryEntriesRepository
$this->add(new Entry(
1,
LocalUsersRepository::getEngineeringLabAccessStudent()->getId(),
LocalDoorsRepository::getAmazonDoor()->getLocation(),
LocalDoorsRepository::getAmazonDoor()->getId(),
false,
Carbon::now()->subDays(1)
));
......@@ -26,7 +26,7 @@ class LocalEntriesRepository extends InMemoryEntriesRepository
$this->add(new Entry(
2,
LocalUsersRepository::getEngineeringLabAccessStudent()->getId(),
LocalDoorsRepository::getTheBatCave()->getLocation(),
LocalDoorsRepository::getTheBatCave()->getId(),
true,
Carbon::now()->subDays(1)
));
......@@ -34,7 +34,7 @@ class LocalEntriesRepository extends InMemoryEntriesRepository
$this->add(new Entry(
3,
LocalUsersRepository::getComputerScienceStudent()->getId(),
LocalDoorsRepository::getAmazonDoor()->getLocation(),
LocalDoorsRepository::getAmazonDoor()->getId(),
true,
Carbon::now()->subMinutes(4)
));
......@@ -42,7 +42,7 @@ class LocalEntriesRepository extends InMemoryEntriesRepository
$this->add(new Entry(
4,
LocalUsersRepository::getComputerScienceStudent()->getId(),
LocalDoorsRepository::getTheBatCave()->getLocation(),
LocalDoorsRepository::getTheBatCave()->getId(),
false,
Carbon::now()->subYear()
));
......
......@@ -24,12 +24,12 @@ class GetAttempts implements GetAttemptsUseCase
/**
* @inheritDoc
*/
public function getBetweenDates(?string $start, ?string $end, ?string $doorLocation, Presenter $presenter): void
public function getBetweenDates(?string $start, ?string $end, ?string $doorId, Presenter $presenter): void
{
$attempts = $this->attempts->getBetween(
self::liberalCastToCarbon($start),
self::liberalCastToCarbon($end),
$doorLocation
$doorId
);
$response = new ResponseModel();
......
......@@ -12,9 +12,9 @@ interface GetAttemptsUseCase
*
* @param string $start
* @param string $end
* @param string|null $doorLocation
* @param string|null $doorId
* @param \Source\UseCases\Attempts\Presenter $presenter
* @throws \Exception
*/
public function getBetweenDates(?string $start, ?string $end, ?string $doorLocation, Presenter $presenter): void;
public function getBetweenDates(?string $start, ?string $end, ?string $doorId, Presenter $presenter): void;
}
......@@ -20,7 +20,7 @@ class WebPresenter extends BasePresenter implements Presenter
$this->attempts = array_map(static function (Attempt $attempt): array {
return [
'id' => $attempt->getId(),
'door_shallow_link' => $attempt->getDoorLocation(),
'door_id' => $attempt->getDoorId(),
'created_at' => self::formatDateTime($attempt->getCreatedAt(), self::HUMAN_DATE_FORMAT) ?? 'Unknown',
];
}, $responseModel->getAttempts());
......@@ -33,7 +33,7 @@ class WebPresenter extends BasePresenter implements Presenter
'attempts' => $this->webPaginate($this->attempts, $appends),
'headers' => [
'ID' => 'id',
'Door' => 'door_shallow_link',
'Door' => 'door_id',
'Attempt Time' => 'created_at',
],
];
......
......@@ -165,7 +165,7 @@ abstract class BasePresenter
return [
'id' => $attempt->getId(),