From 3de9b854b8240db7220ac458d7d23b4350bd5cfe Mon Sep 17 00:00:00 2001 From: amigoscode Date: Sun, 25 Sep 2022 17:15:26 +0100 Subject: [PATCH] Initial CLI Implementation --- src/com/amigoscode/Main.java | 142 +++++++++++++++++ src/com/amigoscode/booking/CarBooking.java | 92 +++++++++++ src/com/amigoscode/booking/CarBookingDao.java | 48 ++++++ .../amigoscode/booking/CarBookingService.java | 150 ++++++++++++++++++ src/com/amigoscode/car/Brand.java | 8 + src/com/amigoscode/car/Car.java | 74 +++++++++ src/com/amigoscode/car/CarDAO.java | 16 ++ src/com/amigoscode/car/CarService.java | 51 ++++++ src/com/amigoscode/user/User.java | 51 ++++++ src/com/amigoscode/user/UserDao.java | 20 +++ src/com/amigoscode/user/UserService.java | 20 +++ 11 files changed, 672 insertions(+) create mode 100644 src/com/amigoscode/Main.java create mode 100644 src/com/amigoscode/booking/CarBooking.java create mode 100644 src/com/amigoscode/booking/CarBookingDao.java create mode 100644 src/com/amigoscode/booking/CarBookingService.java create mode 100644 src/com/amigoscode/car/Brand.java create mode 100644 src/com/amigoscode/car/Car.java create mode 100644 src/com/amigoscode/car/CarDAO.java create mode 100644 src/com/amigoscode/car/CarService.java create mode 100644 src/com/amigoscode/user/User.java create mode 100644 src/com/amigoscode/user/UserDao.java create mode 100644 src/com/amigoscode/user/UserService.java diff --git a/src/com/amigoscode/Main.java b/src/com/amigoscode/Main.java new file mode 100644 index 0000000..9ce69a0 --- /dev/null +++ b/src/com/amigoscode/Main.java @@ -0,0 +1,142 @@ +package com.amigoscode; + +import com.amigoscode.booking.CarBooking; +import com.amigoscode.booking.CarBookingService; +import com.amigoscode.car.Car; +import com.amigoscode.user.User; +import com.amigoscode.user.UserService; + +import java.util.Scanner; +import java.util.UUID; + +public class Main { + + public static void main(String[] args) { + + UserService userService = new UserService(); + CarBookingService carBookingService = new CarBookingService(); + + Scanner scanner = new Scanner(System.in); + + boolean keepLooping = true; + + while (keepLooping) { + try { + displayMenu(); + String choice = scanner.nextLine(); + switch (Integer.parseInt(choice)) { + case 1 -> bookCar(userService, carBookingService, scanner); + case 2 -> displayAllUserBookedCars(userService, carBookingService, scanner); + case 3 -> allBookings(carBookingService); + case 4 -> displayAvailableCars(carBookingService, false); + case 5 -> displayAvailableCars(carBookingService, true); + case 6 -> displayAllUsers(userService); + case 7 -> keepLooping = false; + default -> System.out.println(choice + " not a valid option ❌"); + } + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + } + + private static void allBookings(CarBookingService carBookingService) { + CarBooking[] bookings = carBookingService.getBookings(); + if (bookings.length == 0) { + System.out.println("No bookings available 😕"); + return; + } + for (CarBooking booking : bookings) { + System.out.println("booking = " + booking); + } + } + + private static void displayAllUsers(UserService userService) { + User[] users = userService.getUsers(); + if (users.length == 0) { + System.out.println("❌ No users in the system"); + return; + } + for (User user : users) { + System.out.println(user); + } + } + + private static void displayAvailableCars(CarBookingService carBookingService, boolean isElectric) { + Car[] availableCars = isElectric ? carBookingService.getAvailableElectricCars() : carBookingService.getAvailableCars(); + if (availableCars.length == 0) { + System.out.println("❌ No cars available for renting"); + return; + } + for (Car availableCar : availableCars) { + System.out.println(availableCar); + } + } + + private static void displayAllUserBookedCars(UserService userService, + CarBookingService carBookingService, + Scanner scanner) { + displayAllUsers(userService); + + System.out.println("➡️ select user id"); + String userId = scanner.nextLine(); + + User user = userService.getUserById(UUID.fromString(userId)); + if (user == null) { + System.out.println("❌ No user found with id " + userId); + return; + } + + Car[] userBookedCars = carBookingService.getUserBookedCars(user.getId()); + if (userBookedCars.length == 0) { + System.out.printf("❌ user %s has no cars booked", user); + return; + } + for (Car userBookedCar : userBookedCars) { + System.out.println(userBookedCar); + } + } + + private static void bookCar(UserService userService, CarBookingService carBookingService, Scanner scanner) { + displayAvailableCars(carBookingService, false); + + System.out.println("➡️ select car reg number"); + String regNumber = scanner.nextLine(); + + displayAllUsers(userService); + + System.out.println("➡️ select user id"); + String userId = scanner.nextLine(); + + try { + User user = userService.getUserById(UUID.fromString(userId)); + if (user == null) { + System.out.println("❌ No user found with id " + userId); + } else { + UUID bookingId = carBookingService.bookCar(user, regNumber); + String confirmationMessage = """ + 🎉 Successfully booked car with reg number %s for user %s + Booking ref: %s + """.formatted(regNumber, user, bookingId); + System.out.println(confirmationMessage); + } + + } catch (Exception e) { + System.out.println(e.getMessage()); + } + } + + private static void displayMenu() { + System.out.println(""" + \n + 1️⃣ - Book Car + 2️⃣ - View All User Booked Cars + 3️⃣ - View All Bookings + 4️⃣ - View Available Cars + 5️⃣ - View Available Electric Cars + 6️⃣ - View all users + 7️⃣ - Exit + """); + } + +} \ No newline at end of file diff --git a/src/com/amigoscode/booking/CarBooking.java b/src/com/amigoscode/booking/CarBooking.java new file mode 100644 index 0000000..247a8d0 --- /dev/null +++ b/src/com/amigoscode/booking/CarBooking.java @@ -0,0 +1,92 @@ +package com.amigoscode.booking; + +import com.amigoscode.car.Car; +import com.amigoscode.user.User; + +import java.time.LocalDateTime; +import java.util.Objects; +import java.util.UUID; + +public class CarBooking { + private UUID bookingId; + private User user; + private Car car; + private LocalDateTime bookingTime; + private boolean isCanceled; + + public CarBooking(UUID bookingId, User user, Car car, LocalDateTime bookingTime, boolean isCanceled) { + this.bookingId = bookingId; + this.user = user; + this.car = car; + this.bookingTime = bookingTime; + this.isCanceled = isCanceled; + } + + public CarBooking(UUID bookingId, User user, Car car, LocalDateTime bookingTime) { + this(bookingId, user, car, bookingTime, false); + } + + public UUID getBookingId() { + return bookingId; + } + + public void setBookingId(UUID bookingId) { + this.bookingId = bookingId; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public Car getCar() { + return car; + } + + public void setCar(Car car) { + this.car = car; + } + + public LocalDateTime getBookingTime() { + return bookingTime; + } + + public void setBookingTime(LocalDateTime bookingTime) { + this.bookingTime = bookingTime; + } + + public boolean isCanceled() { + return isCanceled; + } + + public void setCanceled(boolean canceled) { + isCanceled = canceled; + } + + @Override + public String toString() { + return "CarBooking{" + + "bookingId=" + bookingId + + ", user=" + user + + ", car=" + car + + ", bookingTime=" + bookingTime + + ", isCanceled=" + isCanceled + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + CarBooking that = (CarBooking) o; + return isCanceled == that.isCanceled && Objects.equals(bookingId, that.bookingId) && Objects.equals(user, that.user) && Objects.equals(car, that.car) && Objects.equals(bookingTime, that.bookingTime); + } + + @Override + public int hashCode() { + return Objects.hash(bookingId, user, car, bookingTime, isCanceled); + } +} diff --git a/src/com/amigoscode/booking/CarBookingDao.java b/src/com/amigoscode/booking/CarBookingDao.java new file mode 100644 index 0000000..cdd847c --- /dev/null +++ b/src/com/amigoscode/booking/CarBookingDao.java @@ -0,0 +1,48 @@ +package com.amigoscode.booking; + +import java.util.UUID; + +public class CarBookingDao { + + private final static CarBooking[] carBookings; + + static { + carBookings = new CarBooking[10]; + } + + public CarBooking[] getCarBookings() { + return carBookings; + } + + public void book(CarBooking carBooking) { + int nextFreeIndex = -1; + + for (int i = 0; i < carBookings.length; i++) { + if (carBookings[i] == null) { + nextFreeIndex = i; + } + } + + if (nextFreeIndex > -1) { + carBookings[nextFreeIndex] = carBooking; + return; + } + + // full array + // copy all bookings to new array with bigger space + CarBooking[] biggerCarBookings = new CarBooking[carBookings.length + 10]; + + for (int i = 0; i < carBookings.length; i++) { + biggerCarBookings[i] = carBookings[i]; + } + + // finally add new booking + biggerCarBookings[carBookings.length] = carBooking; + + } + + public void cancelCarBooking(UUID id) { + + } + +} diff --git a/src/com/amigoscode/booking/CarBookingService.java b/src/com/amigoscode/booking/CarBookingService.java new file mode 100644 index 0000000..0578152 --- /dev/null +++ b/src/com/amigoscode/booking/CarBookingService.java @@ -0,0 +1,150 @@ +package com.amigoscode.booking; + +import com.amigoscode.car.Car; +import com.amigoscode.car.CarService; +import com.amigoscode.user.User; + +import java.time.LocalDateTime; +import java.util.UUID; + +public class CarBookingService { + + private final CarBookingDao carBookingDao = new CarBookingDao(); + private final CarService carService = new CarService(); + + public UUID bookCar(User user, String regNumber) { + Car[] availableCars = getAvailableCars(); + + if (availableCars.length == 0) { + throw new IllegalStateException("No car available for renting"); + } + + for (Car availableCar : availableCars) { + // let's make sure the car user wants still available + if (availableCar.getRegNumber().equals(regNumber)) { + Car car = carService.getCar(regNumber); + UUID bookingId = UUID.randomUUID(); + carBookingDao.book( + new CarBooking(bookingId, user, car, LocalDateTime.now()) + ); + // at this point we are done therefore we can exit this method + return bookingId; + } + } + throw new IllegalStateException("Already booked. car with regNumber " + regNumber); + } + + public Car[] getUserBookedCars(UUID userId) { + CarBooking[] carBookings = carBookingDao.getCarBookings(); + + int numberOfBookingsForUser = 0; + + for (CarBooking cb : carBookings) { + if (cb != null && cb.getUser().getId().equals(userId)) { + ++numberOfBookingsForUser; + } + } + + if (numberOfBookingsForUser == 0) { + return new Car[0]; + } + + Car[] userCars = new Car[numberOfBookingsForUser]; + + int index = 0; + for (CarBooking carBooking : carBookings) { + if (carBooking != null && carBooking.getUser().getId().equals(userId)) { + userCars[index++] = carBooking.getCar(); + } + } + return userCars; + } + + + public Car[] getAvailableCars() { + return getCars(carService.getAllCars()); + } + + public Car[] getAvailableElectricCars() { + return getCars(carService.getAllElectricCars()); + } + + private Car[] getCars(Car[] cars) { + + // no cars in the system yet + if (cars.length == 0) { + return new Car[0]; + } + + CarBooking[] carBookings = carBookingDao.getCarBookings(); + + // no bookings yet therefore all cars are available + if (carBookings.length == 0) { + return cars; + } + + // this variable is used to create new array for availableCars since we need the size + int availableCarsCount = 0; + + for (Car car : cars) { + // lets check if car part of any booking. if not then its available + boolean booked = false; + for (CarBooking carBooking : carBookings) { + if (carBooking == null || !carBooking.getCar().equals(car)) { + continue; + } + booked = true; + } + if (!booked) { + ++availableCarsCount; + } + } + + Car[] availableCars = new Car[availableCarsCount]; + int index = 0; + + // populate available cars + for (Car car : cars) { + // lets check if car part of any booking. + // if not then its available but this time we add it to available cars + boolean booked = false; + for (CarBooking carBooking : carBookings) { + if (carBooking == null || !carBooking.getCar().equals(car)) { + continue; + } + booked = true; + } + if (!booked) { + availableCars[index++] = car; + } + } + + return availableCars; + } + + public CarBooking[] getBookings() { + CarBooking[] carBookings = carBookingDao.getCarBookings(); + + int numberOfBookings = 0; + + for (CarBooking cb : carBookings) { + if (cb != null) { + ++numberOfBookings; + } + } + + if (numberOfBookings == 0) { + return new CarBooking[0]; + } + + CarBooking[] bookings = new CarBooking[numberOfBookings]; + + int index = 0; + for (CarBooking carBooking : carBookings) { + if (carBooking != null) { + bookings[index++] = carBooking; + } + } + return bookings; + } +} diff --git a/src/com/amigoscode/car/Brand.java b/src/com/amigoscode/car/Brand.java new file mode 100644 index 0000000..a7e0fdd --- /dev/null +++ b/src/com/amigoscode/car/Brand.java @@ -0,0 +1,8 @@ +package com.amigoscode.car; + +public enum Brand { + TESLA, + VW, + MERCEDES, + AUDI +} diff --git a/src/com/amigoscode/car/Car.java b/src/com/amigoscode/car/Car.java new file mode 100644 index 0000000..ac527e4 --- /dev/null +++ b/src/com/amigoscode/car/Car.java @@ -0,0 +1,74 @@ +package com.amigoscode.car; + +import java.math.BigDecimal; +import java.util.Objects; + +public class Car { + private String regNumber; + private BigDecimal rentalPricePerDay; + private Brand brand; + + private boolean isElectric; + + public Car(String regNumber, BigDecimal rentalPricePerDay, Brand brand, boolean isElectric) { + this.regNumber = regNumber; + this.rentalPricePerDay = rentalPricePerDay; + this.brand = brand; + this.isElectric = isElectric; + } + + public String getRegNumber() { + return regNumber; + } + + public void setRegNumber(String regNumber) { + this.regNumber = regNumber; + } + + public BigDecimal getRentalPricePerDay() { + return rentalPricePerDay; + } + + public void setRentalPricePerDay(BigDecimal rentalPricePerDay) { + this.rentalPricePerDay = rentalPricePerDay; + } + + public Brand getBrand() { + return brand; + } + + public void setBrand(Brand brand) { + this.brand = brand; + } + + public boolean isElectric() { + return isElectric; + } + + public void setElectric(boolean electric) { + isElectric = electric; + } + + @Override + public String toString() { + return "Car{" + + "regNumber='" + regNumber + '\'' + + ", rentalPricePerDay=" + rentalPricePerDay + + ", brand=" + brand + + ", isElectric=" + isElectric + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + Car car = (Car) o; + return isElectric == car.isElectric && Objects.equals(regNumber, car.regNumber) && Objects.equals(rentalPricePerDay, car.rentalPricePerDay) && brand == car.brand; + } + + @Override + public int hashCode() { + return Objects.hash(regNumber, rentalPricePerDay, brand, isElectric); + } +} diff --git a/src/com/amigoscode/car/CarDAO.java b/src/com/amigoscode/car/CarDAO.java new file mode 100644 index 0000000..6c6444a --- /dev/null +++ b/src/com/amigoscode/car/CarDAO.java @@ -0,0 +1,16 @@ +package com.amigoscode.car; + +import java.math.BigDecimal; + +public class CarDAO { + + private static final Car[] CARS = { + new Car("1234", new BigDecimal("89.00"), Brand.TESLA, true), + new Car("5678", new BigDecimal("50.00"), Brand.AUDI, false), + new Car("5678", new BigDecimal("77.00"), Brand.MERCEDES, false), + }; + + public Car[] getAllCars() { + return CARS; + } +} diff --git a/src/com/amigoscode/car/CarService.java b/src/com/amigoscode/car/CarService.java new file mode 100644 index 0000000..c0e70cd --- /dev/null +++ b/src/com/amigoscode/car/CarService.java @@ -0,0 +1,51 @@ +package com.amigoscode.car; + +public class CarService { + + private final CarDAO carDAO = new CarDAO(); + + public Car[] getAllCars() { + return carDAO.getAllCars(); + } + + public Car getCar(String regNumber) { + for (Car car : getAllCars()) { + if (regNumber.equals(car.getRegNumber())) { + return car; + } + } + throw new IllegalStateException(String.format("Car with reg %s not found", regNumber)); + } + + public Car[] getAllElectricCars() { + int electricCarsCount = 0; + + Car[] cars = getAllCars(); + + if (cars.length == 0) { + return new Car[0]; + } + + for (Car car : cars) { + if (car.isElectric()) { + electricCarsCount++; + } + } + + if (electricCarsCount == 0) { + return new Car[0]; + } + + Car[] electricCars = new Car[electricCarsCount]; + + int index = 0; + + for (int i = 0; i < cars.length; i++) { + if (cars[i].isElectric()) { + electricCars[index++] = cars[i]; + } + } + + return electricCars; + } +} diff --git a/src/com/amigoscode/user/User.java b/src/com/amigoscode/user/User.java new file mode 100644 index 0000000..f59a7a0 --- /dev/null +++ b/src/com/amigoscode/user/User.java @@ -0,0 +1,51 @@ +package com.amigoscode.user; + +import java.util.Objects; +import java.util.UUID; + +public class User { + private UUID id; + private String name; + + public User(UUID id, String name) { + this.id = id; + this.name = name; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "User{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + User user = (User) o; + return Objects.equals(id, user.id) && Objects.equals(name, user.name); + } + + @Override + public int hashCode() { + return Objects.hash(id, name); + } +} diff --git a/src/com/amigoscode/user/UserDao.java b/src/com/amigoscode/user/UserDao.java new file mode 100644 index 0000000..9727da5 --- /dev/null +++ b/src/com/amigoscode/user/UserDao.java @@ -0,0 +1,20 @@ +package com.amigoscode.user; + +import java.util.UUID; + +public class UserDao { + + private static final User[] users; + + static { + users = new User[]{ + new User(UUID.fromString("8ca51d2b-aaaf-4bf2-834a-e02964e10fc3"), "James"), + new User(UUID.fromString("b10d126a-3608-4980-9f9c-aa179f5cebc3"), "Jamila") + }; + } + + + public User[] getUsers() { + return users; + } +} diff --git a/src/com/amigoscode/user/UserService.java b/src/com/amigoscode/user/UserService.java new file mode 100644 index 0000000..e3bfad7 --- /dev/null +++ b/src/com/amigoscode/user/UserService.java @@ -0,0 +1,20 @@ +package com.amigoscode.user; + +import java.util.UUID; + +public class UserService { + private final UserDao userDao = new UserDao(); + + public User[] getUsers() { + return userDao.getUsers(); + } + + public User getUserById(UUID id) { + for (User user : getUsers()) { + if (user.getId().equals(id)) { + return user; + } + } + return null; + } +}