From 3da67432d01b4b5143ab23b3ade1b60bbbe4dc85 Mon Sep 17 00:00:00 2001 From: Balazs Skerlecz Date: Mon, 5 May 2025 22:13:56 +0200 Subject: [PATCH] PHP engineer challenge --- .../controllers/LoanController.php | 8 +- .../controllers/ReservationController.php | 16 ++-- PHP/library-api-php/data/data.php | 74 +++++++++++++++++++ 3 files changed, 89 insertions(+), 9 deletions(-) diff --git a/PHP/library-api-php/controllers/LoanController.php b/PHP/library-api-php/controllers/LoanController.php index 767f401..3a664a3 100644 --- a/PHP/library-api-php/controllers/LoanController.php +++ b/PHP/library-api-php/controllers/LoanController.php @@ -7,15 +7,15 @@ class LoanController { // GET /loans public function index() { - // TODO: Implement logic to list active loans with borrower and book details. header('Content-Type: application/json'); - echo json_encode(['message' => 'List active loans functionality to be implemented.']); + header('Status: 200'); + echo json_encode(bookList()); } // POST /loans/return public function returnBook() { - // TODO: Implement logic to process the return of a book and calculate fines if overdue. header('Content-Type: application/json'); - echo json_encode(['message' => 'Return book functionality to be implemented.']); + header('Status: 200'); + echo json_encode(returnBook($_POST['bookId'])); } } diff --git a/PHP/library-api-php/controllers/ReservationController.php b/PHP/library-api-php/controllers/ReservationController.php index cfd79fe..8b9a6a1 100644 --- a/PHP/library-api-php/controllers/ReservationController.php +++ b/PHP/library-api-php/controllers/ReservationController.php @@ -6,15 +6,21 @@ class ReservationController { // POST /reservations public function reserve() { - // TODO: Implement logic to reserve a book currently on loan. - header('Content-Type: application/json'); - echo json_encode(['message' => 'Reserve book functionality to be implemented.']); + $reservation = reservation($_POST['bookId'], $_POST['borrowerId']); + if ($reservation === NULL) { + header('Content-Type: application/json'); + header('Status: 404'); + } else { + header('Content-Type: application/json'); + header('Status: 200'); + echo json_encode($reservation); + } } // GET /reservations public function status() { - // TODO: Implement logic to return reservation status for a given borrower and book. header('Content-Type: application/json'); - echo json_encode(['message' => 'Reservation status functionality to be implemented.']); + header('Status: 200'); + echo json_encode(reservationStatus($_GET['bookId'])); } } diff --git a/PHP/library-api-php/data/data.php b/PHP/library-api-php/data/data.php index 1ff8d5a..ad69831 100644 --- a/PHP/library-api-php/data/data.php +++ b/PHP/library-api-php/data/data.php @@ -29,3 +29,77 @@ // Fines and reservations (empty arrays to start) $fines = []; $reservations = []; + +// + +function maxId($a) { + return array_reduce(fn($c, $o) => $c > $o->id ? $c : $o->id,$a); +} + +function book($bookId) { + return array_first(array_filter(fn($o) => $bookId==$o->bookId,$books)); +} + +function bookList() { + return array_map(function($o) { + $book = book($o->bookId); + return ['title' => $book->title, 'isOnLoan'=>$o->isOnLoan,'loanEndDate'=>$o->loanEndDate,'borrowerId'=>$o->borrowerId]; + },$bookStocks); +} + +function fineAmount($bookStock) { + // TODO calculate the fine amount +} + +function fineDetails($bookStock) { + // TODO fine details +} + +function returnBook($bookId) { + $bookStock = array_first(array_filter(fn($o) => $bookId ==$o->bookId, $bookStocks)); + $bookStocks = array_filter(fn($o) => $o->$bookId != $bookId,$bookStocks); + + if (strtotime($bookStock->loadEndDate) < strtotime(date('now'))) { + return new Fine($id,$bookStock->borrowerId,fineAmount($bookStock), fineDetails($bookStock)); + } else { + return []; + } +} + +function reservation($bookId, $borrowerId) { + $bookReservations = array_filter( + fn($o) => $o->bookId == $bookId + ,$reservations + ); + + if (count($bookReservations)) { + $id = maxId($reservations) + 1; + $reservation = new Reservation($id, $bookId, $borrowerId, date('now')); + $reservations[]=$reservation; + return []; + } + + return NULL; +} + +function reservationStatus($bookId) { + $available = true; + $reservedAt = NULL; + + $bookReservations = array_filter( + fn($o) => $o->$bookId == $bookId + ,$reservations + ); + + if (count($bookReservations)) { + $available = false; + $reservedAt = array_reduce( + fn($v, $o) => (strtotime($o->reservedAt) > strtotime($v)) ? $o->reservedAt : $v + ,$bookReservations); + } + + return [ + 'available' => $available, + 'reservedAt' => $reservedAt + ]; +}