From 435f3172d70f949b39d913f2f0722e8074ba86b8 Mon Sep 17 00:00:00 2001 From: Viktor Lindell Date: Thu, 18 Dec 2025 15:17:17 +0100 Subject: [PATCH 1/5] viktor-Car --- src/main/java/org/example/App.java | 55 ++++++++++++++++++++- src/main/java/org/example/Car.java | 42 ++++++++++++++++ src/main/resources/META-INF/persistence.xml | 24 +++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/main/java/org/example/Car.java create mode 100644 src/main/resources/META-INF/persistence.xml diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index 165e5cd5..d4c0e508 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -1,7 +1,60 @@ package org.example; +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; + public class App { public static void main(String[] args) { - System.out.println("Hello There!"); + EntityManagerFactory emf = Persistence.createEntityManagerFactory("carRentalPU"); + EntityManager em = emf.createEntityManager(); + + em.getTransaction().begin(); + + // Rensa tabellen innan vi lägger in nya bilar + em.createQuery("DELETE FROM Car").executeUpdate(); + + // Skapa och persist 20 bilar med rimliga dagspriser + em.persist(createCar("Volvo", "XC90", 2025, "Lyxbil", 800_000)); + em.persist(createCar("BMW", "7 Series", 2024, "Lyxbil", 1_000_000)); + em.persist(createCar("Audi", "A8", 2023, "Lyxbil", 900_000)); + em.persist(createCar("Toyota", "Corolla", 2022, "Personbil", 200_000)); + em.persist(createCar("Honda", "Civic", 2021, "Personbil", 190_000)); + em.persist(createCar("Ford", "Focus", 2022, "Personbil", 210_000)); + em.persist(createCar("Mercedes", "Sprinter", 2023, "Minibuss", 350_000)); + em.persist(createCar("Volkswagen", "Transporter", 2023, "Minibuss", 330_000)); + em.persist(createCar("Renault", "Kangoo", 2022, "Minibuss", 300_000)); + em.persist(createCar("Fiat", "500", 2023, "Småbil", 120_000)); + em.persist(createCar("Mini", "Cooper", 2022, "Småbil", 150_000)); + em.persist(createCar("Volkswagen", "Up!", 2022, "Småbil", 110_000)); + em.persist(createCar("Porsche", "911", 2025, "Sportbil", 1_500_000)); + em.persist(createCar("Ferrari", "Roma", 2024, "Sportbil", 2_000_000)); + em.persist(createCar("Lamborghini", "Huracan", 2025, "Sportbil", 2_500_000)); + em.persist(createCar("Tesla", "Model S", 2023, "Lyxbil", 900_000)); + em.persist(createCar("Kia", "Rio", 2022, "Småbil", 130_000)); + em.persist(createCar("Hyundai", "i30", 2023, "Personbil", 195_000)); + em.persist(createCar("Opel", "Vivaro", 2022, "Minibuss", 320_000)); + em.persist(createCar("Jaguar", "F-Type", 2024, "Sportbil", 1_600_000)); + + em.getTransaction().commit(); + em.close(); + emf.close(); + + System.out.println("20 cars saved successfully!"); + } + + // Skapar bil och sätter dagspris till 0,5% av priset + private static Car createCar(String brand, String model, int year, String type, double price) { + Car car = new Car(); + car.setBrand(brand); + car.setModel(model); + car.setYear(year); + car.setType(type); + car.setPrice(price); + car.setDailyPrice(price * 0.005); // 0,5% av totalpris + return car; } } + + + diff --git a/src/main/java/org/example/Car.java b/src/main/java/org/example/Car.java new file mode 100644 index 00000000..cd1072d0 --- /dev/null +++ b/src/main/java/org/example/Car.java @@ -0,0 +1,42 @@ +package org.example; + +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; + +@Entity +public class Car { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String brand; + private String model; + private int year; + private String type; + private double price; + private double dailyPrice; // ny egenskap + + // Getters och setters + public Long getId() { return id; } + + public String getBrand() { return brand; } + public void setBrand(String brand) { this.brand = brand; } + + public String getModel() { return model; } + public void setModel(String model) { this.model = model; } + + public int getYear() { return year; } + public void setYear(int year) { this.year = year; } + + public String getType() { return type; } + public void setType(String type) { this.type = type; } + + public double getPrice() { return price; } + public void setPrice(double price) { this.price = price; } + + public double getDailyPrice() { return dailyPrice; } + public void setDailyPrice(double dailyPrice) { this.dailyPrice = dailyPrice; } +} + diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml new file mode 100644 index 00000000..bade027b --- /dev/null +++ b/src/main/resources/META-INF/persistence.xml @@ -0,0 +1,24 @@ + + + + org.example.Car + + + + + + + + + + + + + + + From 9fedb6cc8cc004513c29e67759495159a7e77cda Mon Sep 17 00:00:00 2001 From: Viktor Lindell Date: Thu, 18 Dec 2025 15:18:06 +0100 Subject: [PATCH 2/5] viktor-Car --- JavaJPA.iml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 JavaJPA.iml diff --git a/JavaJPA.iml b/JavaJPA.iml new file mode 100644 index 00000000..51151a37 --- /dev/null +++ b/JavaJPA.iml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file From 21bfe11aa1baa87006b4087b7a00c56937cce5fd Mon Sep 17 00:00:00 2001 From: Viktor Lindell Date: Tue, 6 Jan 2026 12:58:31 +0100 Subject: [PATCH 3/5] viktor-Car --- src/main/java/org/example/App.java | 7 +- src/main/java/org/example/Car.java | 42 ---------- src/main/java/org/example/model/Booking.java | 83 +++++++++++++++++-- src/main/java/org/example/model/Car.java | 2 +- src/main/java/org/example/model/Extra.java | 19 +++++ src/main/java/org/example/model/Location.java | 24 ++++++ .../org/example/repository/CarRepository.java | 2 +- src/main/java/org/example/util/JPAUtil.java | 14 ++++ src/main/resources/META-INF/persistence.xml | 2 +- 9 files changed, 139 insertions(+), 56 deletions(-) delete mode 100644 src/main/java/org/example/Car.java create mode 100644 src/main/java/org/example/model/Extra.java create mode 100644 src/main/java/org/example/model/Location.java create mode 100644 src/main/java/org/example/util/JPAUtil.java diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index bf18517d..402e4d30 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -1,11 +1,13 @@ package org.example; +import org.example.model.Car; // ✅ Rätt import import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; public class App { public static void main(String[] args) { + // Skapa EntityManager EntityManagerFactory emf = Persistence.createEntityManagerFactory("carRentalPU"); EntityManager em = emf.createEntityManager(); @@ -45,10 +47,7 @@ public static void main(String[] args) { // Skapar bil och sätter dagspris till 0,5% av priset private static Car createCar(String brand, String model, int year, String type, double price) { - - Car car = new Car(); - - + Car car = new Car(); // ✅ korrekt syntax car.setBrand(brand); car.setModel(model); car.setYear(year); diff --git a/src/main/java/org/example/Car.java b/src/main/java/org/example/Car.java deleted file mode 100644 index cd1072d0..00000000 --- a/src/main/java/org/example/Car.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.example; - -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; - -@Entity -public class Car { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String brand; - private String model; - private int year; - private String type; - private double price; - private double dailyPrice; // ny egenskap - - // Getters och setters - public Long getId() { return id; } - - public String getBrand() { return brand; } - public void setBrand(String brand) { this.brand = brand; } - - public String getModel() { return model; } - public void setModel(String model) { this.model = model; } - - public int getYear() { return year; } - public void setYear(int year) { this.year = year; } - - public String getType() { return type; } - public void setType(String type) { this.type = type; } - - public double getPrice() { return price; } - public void setPrice(double price) { this.price = price; } - - public double getDailyPrice() { return dailyPrice; } - public void setDailyPrice(double dailyPrice) { this.dailyPrice = dailyPrice; } -} - diff --git a/src/main/java/org/example/model/Booking.java b/src/main/java/org/example/model/Booking.java index 52fd6bb4..f3564315 100644 --- a/src/main/java/org/example/model/Booking.java +++ b/src/main/java/org/example/model/Booking.java @@ -1,22 +1,20 @@ package org.example.model; import jakarta.persistence.*; - - -import javax.tools.DocumentationTool; -import javax.xml.stream.Location; import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.List; @Entity public class Booking { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne(optional = false) @JoinColumn(name = "customer_id") - Customer customer; + private Customer customer; @ManyToOne(optional = false) @JoinColumn(name = "car_id") @@ -41,18 +39,89 @@ public class Booking { private LocalDate startDate; private LocalDate endDate; + @Enumerated(EnumType.STRING) + private BookingStatus status; + + private LocalDateTime createdAt; + + // ---------------------------- + // Konstruktörer + // ---------------------------- protected Booking() { // JPA requires a no-arg constructor } - public Booking(Customer customer, Car car, Location pickupLocation, Location dropoffLocation, LocalDate startDate, LocalDate endDate) { + public Booking(Customer customer, Car car, Location pickupLocation, Location dropoffLocation, + LocalDate startDate, LocalDate endDate) { this.customer = customer; this.car = car; + this.pickupLocation = pickupLocation; + this.dropoffLocation = dropoffLocation; this.startDate = startDate; this.endDate = endDate; this.status = BookingStatus.RESERVED; this.createdAt = LocalDateTime.now(); - } + // ---------------------------- + // Getters och setters + // ---------------------------- + public Long getId() { return id; } + + public Customer getCustomer() { return customer; } + public void setCustomer(Customer customer) { this.customer = customer; } + + public Car getCar() { return car; } + public void setCar(Car car) { this.car = car; } + + public Location getPickupLocation() { return pickupLocation; } + public void setPickupLocation(Location pickupLocation) { this.pickupLocation = pickupLocation; } + + public Location getDropoffLocation() { return dropoffLocation; } + public void setDropoffLocation(Location dropoffLocation) { this.dropoffLocation = dropoffLocation; } + + public List getExtras() { return extras; } + public void setExtras(List extras) { this.extras = extras; } + + public Payment getPayment() { return payment; } + public void setPayment(Payment payment) { this.payment = payment; } + + public LocalDate getStartDate() { return startDate; } + public void setStartDate(LocalDate startDate) { this.startDate = startDate; } + + public LocalDate getEndDate() { return endDate; } + public void setEndDate(LocalDate endDate) { this.endDate = endDate; } + + public BookingStatus getStatus() { return status; } + public void setStatus(BookingStatus status) { this.status = status; } + + public LocalDateTime getCreatedAt() { return createdAt; } + public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } + + // ---------------------------- + // Inner class Extra + // ---------------------------- + @Entity + public static class Extra { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + private double price; + + protected Extra() {} + + public Extra(String name, double price) { + this.name = name; + this.price = price; + } + + public Long getId() { return id; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } + public double getPrice() { return price; } + public void setPrice(double price) { this.price = price; } + } } + diff --git a/src/main/java/org/example/model/Car.java b/src/main/java/org/example/model/Car.java index b5ec40f0..27bb15d7 100644 --- a/src/main/java/org/example/model/Car.java +++ b/src/main/java/org/example/model/Car.java @@ -1,4 +1,4 @@ -package org.example; +package org.example.model; import jakarta.persistence.Entity; import jakarta.persistence.Id; diff --git a/src/main/java/org/example/model/Extra.java b/src/main/java/org/example/model/Extra.java new file mode 100644 index 00000000..6a6b87a9 --- /dev/null +++ b/src/main/java/org/example/model/Extra.java @@ -0,0 +1,19 @@ +package org.example.model; + +public class Extra { + private String name; + private double price; + + // Konstruktor + public Extra(String name, double price) { + this.name = name; + this.price = price; + } + + // Getters och setters + public String getName() { return name; } + public void setName(String name) { this.name = name; } + + public double getPrice() { return price; } + public void setPrice(double price) { this.price = price; } +} diff --git a/src/main/java/org/example/model/Location.java b/src/main/java/org/example/model/Location.java new file mode 100644 index 00000000..24f1e81a --- /dev/null +++ b/src/main/java/org/example/model/Location.java @@ -0,0 +1,24 @@ +package org.example.model; + +import jakarta.persistence.*; + +@Entity +public class Location { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + protected Location() {} + + public Location(String name) { + this.name = name; + } + + public Long getId() { return id; } + public String getName() { return name; } + public void setName(String name) { this.name = name; } +} + diff --git a/src/main/java/org/example/repository/CarRepository.java b/src/main/java/org/example/repository/CarRepository.java index cff21c7b..d4f473ab 100644 --- a/src/main/java/org/example/repository/CarRepository.java +++ b/src/main/java/org/example/repository/CarRepository.java @@ -1,10 +1,10 @@ package org.example.repository; import org.example.model.Car; -import org.example.util.JPAUtil; import jakarta.persistence.EntityManager; import java.util.List; +import org.example.util.JPAUtil; public class CarRepository { diff --git a/src/main/java/org/example/util/JPAUtil.java b/src/main/java/org/example/util/JPAUtil.java new file mode 100644 index 00000000..df1f9b38 --- /dev/null +++ b/src/main/java/org/example/util/JPAUtil.java @@ -0,0 +1,14 @@ +package org.example.util; + +import jakarta.persistence.EntityManager; +import jakarta.persistence.EntityManagerFactory; +import jakarta.persistence.Persistence; + +public class JPAUtil { + private static final EntityManagerFactory emf = + Persistence.createEntityManagerFactory("carRentalPU"); + + public static EntityManager getEntityManager() { + return emf.createEntityManager(); + } +} diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 0377b867..9abd48a0 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -2,7 +2,7 @@ version="3.0"> - org.example.Car + org.example.model.Car From a3152ebe1a1ae27cce03bea3149d5614dbf2e65d Mon Sep 17 00:00:00 2001 From: Viktor Lindell Date: Mon, 12 Jan 2026 20:14:30 +0100 Subject: [PATCH 4/5] viktor-Car --- pom.xml | 106 ++++++++++---- src/main/java/org/example/App.java | 100 ++++++------- src/main/java/org/example/Main.java | 7 + .../example/controller/BookingController.java | 88 ++++++++++++ .../org/example/controller/CarController.java | 62 +++++++- .../controller/CustomerController.java | 30 +++- .../controller/MainViewController.java | 36 +++++ src/main/java/org/example/model/Booking.java | 115 +++------------ src/main/java/org/example/model/Car.java | 55 +++++--- src/main/java/org/example/model/CarType.java | 8 ++ src/main/java/org/example/model/Customer.java | 56 +++++++- src/main/java/org/example/model/Extra.java | 22 ++- .../example/repository/BookingRepository.java | 29 ++++ .../org/example/repository/CarRepository.java | 32 +++-- .../repository/CustomerRepository.java | 37 +++++ .../org/example/service/BookingService.java | 42 ++++++ .../java/org/example/service/CarService.java | 25 ++++ .../org/example/service/CustomerService.java | 25 ++++ .../org/example/util/DataInitializer.java | 53 +++++++ src/main/java/org/example/util/JPAUtil.java | 10 ++ src/main/resources/META-INF/persistence.xml | 33 +++-- src/main/resources/css/main.css | 133 +++++++++++++++++- src/main/resources/fxml/booking_view.fxml | 71 ++++++++++ src/main/resources/fxml/car_view.fxml | 40 ++++++ src/main/resources/fxml/customer_view.fxml | 18 +++ src/main/resources/fxml/main_view.fxml | 35 ++++- 26 files changed, 1032 insertions(+), 236 deletions(-) create mode 100644 src/main/java/org/example/Main.java create mode 100644 src/main/java/org/example/model/CarType.java create mode 100644 src/main/java/org/example/util/DataInitializer.java diff --git a/pom.xml b/pom.xml index d586b911..6e5f5df6 100644 --- a/pom.xml +++ b/pom.xml @@ -1,7 +1,8 @@ + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 + http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 org.example @@ -9,46 +10,101 @@ 1.0-SNAPSHOT - 25 + 17 UTF-8 - 6.0.1 - 3.27.6 - 5.21.0 + 21.0.1 + 6.4.1.Final + + - org.junit.jupiter - junit-jupiter - ${junit.jupiter.version} - test + org.openjfx + javafx-controls + ${javafx.version} - org.assertj - assertj-core - ${assertj.core.version} - test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test + org.openjfx + javafx-fxml + ${javafx.version} + + org.hibernate.orm hibernate-core - 7.2.0.Final + ${hibernate.version} + + jakarta.persistence + jakarta.persistence-api + 3.1.0 + + + com.mysql mysql-connector-j - 9.5.0 - runtime + 9.1.0 + + - io.github.classgraph - classgraph - 4.8.184 + org.junit.jupiter + junit-jupiter-api + 5.10.1 + test + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.13.0 + + 17 + + + + + + org.openjfx + javafx-maven-plugin + 0.0.8 + + org.example.Main + + + + + org.apache.maven.plugins + maven-shade-plugin + 3.5.0 + + + package + + shade + + + + + org.example.Main + + + META-INF/persistence.xml + + + + + + + + + + + + diff --git a/src/main/java/org/example/App.java b/src/main/java/org/example/App.java index 402e4d30..9786ddc5 100644 --- a/src/main/java/org/example/App.java +++ b/src/main/java/org/example/App.java @@ -1,62 +1,54 @@ package org.example; -import org.example.model.Car; // ✅ Rätt import import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.Persistence; - -public class App { - public static void main(String[] args) { - // Skapa EntityManager - EntityManagerFactory emf = Persistence.createEntityManagerFactory("carRentalPU"); - EntityManager em = emf.createEntityManager(); - - em.getTransaction().begin(); - - // Rensa tabellen innan vi lägger in nya bilar - em.createQuery("DELETE FROM Car").executeUpdate(); - - // Skapa och persist 20 bilar med rimliga dagspriser - em.persist(createCar("Volvo", "XC90", 2025, "Lyxbil", 800_000)); - em.persist(createCar("BMW", "7 Series", 2024, "Lyxbil", 1_000_000)); - em.persist(createCar("Audi", "A8", 2023, "Lyxbil", 900_000)); - em.persist(createCar("Toyota", "Corolla", 2022, "Personbil", 200_000)); - em.persist(createCar("Honda", "Civic", 2021, "Personbil", 190_000)); - em.persist(createCar("Ford", "Focus", 2022, "Personbil", 210_000)); - em.persist(createCar("Mercedes", "Sprinter", 2023, "Minibuss", 350_000)); - em.persist(createCar("Volkswagen", "Transporter", 2023, "Minibuss", 330_000)); - em.persist(createCar("Renault", "Kangoo", 2022, "Minibuss", 300_000)); - em.persist(createCar("Fiat", "500", 2023, "Småbil", 120_000)); - em.persist(createCar("Mini", "Cooper", 2022, "Småbil", 150_000)); - em.persist(createCar("Volkswagen", "Up!", 2022, "Småbil", 110_000)); - em.persist(createCar("Porsche", "911", 2025, "Sportbil", 1_500_000)); - em.persist(createCar("Ferrari", "Roma", 2024, "Sportbil", 2_000_000)); - em.persist(createCar("Lamborghini", "Huracan", 2025, "Sportbil", 2_500_000)); - em.persist(createCar("Tesla", "Model S", 2023, "Lyxbil", 900_000)); - em.persist(createCar("Kia", "Rio", 2022, "Småbil", 130_000)); - em.persist(createCar("Hyundai", "i30", 2023, "Personbil", 195_000)); - em.persist(createCar("Opel", "Vivaro", 2022, "Minibuss", 320_000)); - em.persist(createCar("Jaguar", "F-Type", 2024, "Sportbil", 1_600_000)); - - em.getTransaction().commit(); - em.close(); - emf.close(); - - System.out.println("20 cars saved successfully!"); +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.stage.Stage; +import org.example.util.DataInitializer; +import org.example.util.JPAUtil; + +public class App extends Application { +// ... existing code ... + + @Override + public void start(Stage stage) { + try { + // 1. Initiera databasen och ladda testdata (seed) + initDatabase(); + + // 2. Ladda gränssnittet + FXMLLoader fxmlLoader = new FXMLLoader(App.class.getResource("/fxml/main_view.fxml")); + Scene scene = new Scene(fxmlLoader.load()); + + // Koppla på CSS för "Hertz-looken" + scene.getStylesheets().add(App.class.getResource("/css/main.css").toExternalForm()); + + stage.setTitle("Hertz Biluthyrning - Grupp 7"); + stage.setScene(scene); + stage.show(); + } catch (Exception e) { + e.printStackTrace(); + System.err.println("Kunde inte starta applikationen: " + e.getMessage()); + } } - // Skapar bil och sätter dagspris till 0,5% av priset - private static Car createCar(String brand, String model, int year, String type, double price) { - Car car = new Car(); // ✅ korrekt syntax - car.setBrand(brand); - car.setModel(model); - car.setYear(year); - car.setType(type); - car.setPrice(price); - car.setDailyPrice(price * 0.005); // 0,5% av totalpris - return car; + private void initDatabase() { + EntityManager em = JPAUtil.getEntityManagerFactory().createEntityManager(); + try { + DataInitializer.seed(em); + } finally { + em.close(); + } } -} - + @Override + public void stop() { + // Stäng ner JPA snyggt när appen stängs + JPAUtil.shutdown(); + } + public static void main(String[] args) { + launch(); + } +} diff --git a/src/main/java/org/example/Main.java b/src/main/java/org/example/Main.java new file mode 100644 index 00000000..6bf26dd2 --- /dev/null +++ b/src/main/java/org/example/Main.java @@ -0,0 +1,7 @@ +package org.example; + +public class Main { + public static void main(String[] args) { + App.main(args); + } +} diff --git a/src/main/java/org/example/controller/BookingController.java b/src/main/java/org/example/controller/BookingController.java index 7c7a57e5..f5edccb3 100644 --- a/src/main/java/org/example/controller/BookingController.java +++ b/src/main/java/org/example/controller/BookingController.java @@ -1,4 +1,92 @@ package org.example.controller; +import javafx.fxml.FXML; +import javafx.scene.control.*; +import org.example.model.*; +import org.example.service.*; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + public class BookingController { + + @FXML private ComboBox carComboBox; + @FXML private DatePicker startDatePicker; + @FXML private DatePicker endDatePicker; + @FXML private TextField customerEmailField; + @FXML private Label daysLabel; + @FXML private Label totalAmountLabel; + @FXML private Label carPriceLabel; + + private final BookingService bookingService = new BookingService(); + private final CarService carService = new CarService(); + private final CustomerService customerService = new CustomerService(); + + @FXML + public void initialize() { + // Ladda tillgängliga bilar i dropdownen + carComboBox.getItems().setAll(carService.getAvailableCars()); + + // Sätt dagens datum som default startdatum + startDatePicker.setValue(LocalDate.now()); + endDatePicker.setValue(LocalDate.now().plusDays(1)); + + updatePriceDisplay(); + } + + @FXML + public void updatePriceDisplay() { + Car selectedCar = carComboBox.getValue(); + LocalDate start = startDatePicker.getValue(); + LocalDate end = endDatePicker.getValue(); + + if (selectedCar != null && start != null && end != null) { + Booking tempBooking = new Booking(null, selectedCar, start, end); + long days = tempBooking.getDurationInDays(); + double total = bookingService.calculateTotalPrice(tempBooking); + + daysLabel.setText(String.valueOf(days)); + carPriceLabel.setText(String.format("%.2f kr", selectedCar.getDailyPrice() * days)); + totalAmountLabel.setText(String.format("%.2f kr", total)); + } + } + + @FXML + public void onConfirmBooking() { + Car car = carComboBox.getValue(); + String email = customerEmailField.getText(); + + if (car == null || email.isEmpty()) { + showError("Vänligen fyll i alla uppgifter."); + return; + } + + // Hämta eller skapa kund + Customer customer = customerService.findCustomerByEmail(email) + .orElse(new Customer("Okänd", "Kund", email)); + + if (customer.getId() == null) customerService.saveCustomer(customer); + + Booking booking = new Booking(customer, car, startDatePicker.getValue(), endDatePicker.getValue()); + + try { + bookingService.createBooking(booking); + showInfo("Bokning bekräftad!", "Bilen är nu reserverad."); + } catch (Exception e) { + showError("Kunde inte skapa bokning: " + e.getMessage()); + } + } + + private void showInfo(String title, String content) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(title); + alert.setContentText(content); + alert.showAndWait(); + } + + private void showError(String content) { + Alert alert = new Alert(Alert.AlertType.ERROR); + alert.setContentText(content); + alert.showAndWait(); + } } diff --git a/src/main/java/org/example/controller/CarController.java b/src/main/java/org/example/controller/CarController.java index 49de64a5..3538e1c9 100644 --- a/src/main/java/org/example/controller/CarController.java +++ b/src/main/java/org/example/controller/CarController.java @@ -1,11 +1,61 @@ package org.example.controller; +import javafx.beans.property.SimpleStringProperty; +import javafx.fxml.FXML; +import javafx.scene.control.TableColumn; +import javafx.scene.control.TableView; +import javafx.scene.control.TextField; +import javafx.scene.control.cell.PropertyValueFactory; +import org.example.model.Car; +import org.example.model.CarType; +import org.example.service.CarService; + public class CarController { - boolean CarDamage=false; - boolean CarRented=false; - boolean CarAvailable=true; - boolean CarBooked=false; - boolean CarBroke=false; - boolean CarReturned=false; + @FXML private TableView carTable; + @FXML private TableColumn brandColumn; + @FXML private TableColumn modelColumn; + @FXML private TableColumn typeColumn; + @FXML + private TableColumn priceColumn; + @FXML + private TableColumn statusColumn; + @FXML + private TextField searchField; + + private final CarService carService = new CarService(); + + @FXML + public void initialize() { + // Koppla kolumnerna till Car-modellens fält via getters + brandColumn.setCellValueFactory(new PropertyValueFactory<>("brand")); + modelColumn.setCellValueFactory(new PropertyValueFactory<>("model")); + typeColumn.setCellValueFactory(new PropertyValueFactory<>("type")); + priceColumn.setCellValueFactory(new PropertyValueFactory<>("dailyPrice")); + + // Specialhantering för status-kolumnen för att visa ikoner/text istället för boolean + statusColumn.setCellValueFactory(cellData -> { + boolean available = cellData.getValue().isAvailable(); + boolean damaged = cellData.getValue().isDamaged(); + + if (damaged) return new SimpleStringProperty("🛠 Trasig"); + return new SimpleStringProperty(available ? "✅ Tillgänglig" : "❌ Uthyrd"); + }); + + loadCars(); + } + + private void loadCars() { + // Vi hämtar alla bilar för att visa hela vagnparken i tabellen + carTable.getItems().setAll(carService.getAllCars()); + } + + @FXML + public void handleBookingAction() { + Car selectedCar = carTable.getSelectionModel().getSelectedItem(); + if (selectedCar != null && selectedCar.isAvailable() && !selectedCar.isDamaged()) { + System.out.println("Bokning påbörjad för: " + selectedCar.getBrand() + " " + selectedCar.getModel()); + // Här kan man senare lägga till logik för att automatiskt hoppa till bokningsvyn + } + } } diff --git a/src/main/java/org/example/controller/CustomerController.java b/src/main/java/org/example/controller/CustomerController.java index 6cbcc5d9..59c63ef6 100644 --- a/src/main/java/org/example/controller/CustomerController.java +++ b/src/main/java/org/example/controller/CustomerController.java @@ -1,5 +1,31 @@ package org.example.controller; -public interface CustomerController { - int addCustomer(); +import javafx.fxml.FXML; +import javafx.scene.control.TextField; +import org.example.model.Customer; +import org.example.service.CustomerService; + +public class CustomerController { + + @FXML + private TextField firstNameField; + @FXML + private TextField lastNameField; + @FXML + private TextField emailField; + + private final CustomerService customerService = new CustomerService(); + + @FXML + public void handleAddCustomer() { + String firstName = firstNameField.getText(); + String lastName = lastNameField.getText(); + String email = emailField.getText(); + + // Nu matchar vi konstruktorn Customer(String, String, String) + Customer customer = new Customer(firstName, lastName, email); + customerService.saveCustomer(customer); + + System.out.println("Kund sparad: " + firstName + " " + lastName); + } } diff --git a/src/main/java/org/example/controller/MainViewController.java b/src/main/java/org/example/controller/MainViewController.java index aa1a0cdc..6b188b2d 100644 --- a/src/main/java/org/example/controller/MainViewController.java +++ b/src/main/java/org/example/controller/MainViewController.java @@ -1,4 +1,40 @@ package org.example.controller; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.layout.StackPane; +import java.io.IOException; + public class MainViewController { + + @FXML + private StackPane contentArea; + + @FXML + public void showCarView() { + loadView("/fxml/car_view.fxml"); + } + + @FXML + public void showBookingView() { + loadView("/fxml/booking_view.fxml"); + } + + @FXML + public void showCustomerView() { + loadView("/fxml/customer_view.fxml"); + } + + private void loadView(String fxmlPath) { + try { + Parent view = FXMLLoader.load(getClass().getResource(fxmlPath)); + contentArea.getChildren().setAll(view); + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Kunde inte ladda vyn: " + fxmlPath); + } + } } + + diff --git a/src/main/java/org/example/model/Booking.java b/src/main/java/org/example/model/Booking.java index f3564315..e64a340f 100644 --- a/src/main/java/org/example/model/Booking.java +++ b/src/main/java/org/example/model/Booking.java @@ -2,126 +2,51 @@ import jakarta.persistence.*; import java.time.LocalDate; -import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; @Entity public class Booking { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - - @ManyToOne(optional = false) - @JoinColumn(name = "customer_id") - private Customer customer; - - @ManyToOne(optional = false) - @JoinColumn(name = "car_id") - private Car car; - - @ManyToOne - @JoinColumn(name = "pickup_location_id") - private Location pickupLocation; - - @ManyToOne - @JoinColumn(name = "dropoff_location_id") - private Location dropoffLocation; - - @OneToMany - @JoinColumn(name = "booking_id") - private List extras; - - @OneToOne - @JoinColumn(name = "payment_id") - private Payment payment; - private LocalDate startDate; private LocalDate endDate; - @Enumerated(EnumType.STRING) private BookingStatus status; - private LocalDateTime createdAt; + @ManyToOne + private Car car; - // ---------------------------- - // Konstruktörer - // ---------------------------- - protected Booking() { - // JPA requires a no-arg constructor - } + @ManyToOne + private Customer customer; + + @ManyToMany + private List extras = new ArrayList<>(); - public Booking(Customer customer, Car car, Location pickupLocation, Location dropoffLocation, - LocalDate startDate, LocalDate endDate) { + public Booking(Customer customer, Car car, LocalDate startDate, LocalDate endDate) { this.customer = customer; this.car = car; - this.pickupLocation = pickupLocation; - this.dropoffLocation = dropoffLocation; this.startDate = startDate; this.endDate = endDate; this.status = BookingStatus.RESERVED; - this.createdAt = LocalDateTime.now(); } - // ---------------------------- - // Getters och setters - // ---------------------------- - public Long getId() { return id; } + public void addExtra(Extra extra) { + this.extras.add(extra); + } - public Customer getCustomer() { return customer; } - public void setCustomer(Customer customer) { this.customer = customer; } + public long getDurationInDays() { + if (startDate == null || endDate == null) return 0; + return java.time.temporal.ChronoUnit.DAYS.between(startDate, endDate); + } + // Getters och Setters + public Long getId() { return id; } + public Customer getCustomer() { return customer; } public Car getCar() { return car; } - public void setCar(Car car) { this.car = car; } - - public Location getPickupLocation() { return pickupLocation; } - public void setPickupLocation(Location pickupLocation) { this.pickupLocation = pickupLocation; } - - public Location getDropoffLocation() { return dropoffLocation; } - public void setDropoffLocation(Location dropoffLocation) { this.dropoffLocation = dropoffLocation; } - - public List getExtras() { return extras; } - public void setExtras(List extras) { this.extras = extras; } - - public Payment getPayment() { return payment; } - public void setPayment(Payment payment) { this.payment = payment; } - public LocalDate getStartDate() { return startDate; } - public void setStartDate(LocalDate startDate) { this.startDate = startDate; } - public LocalDate getEndDate() { return endDate; } - public void setEndDate(LocalDate endDate) { this.endDate = endDate; } - - public BookingStatus getStatus() { return status; } + public List getExtras() { return extras; } public void setStatus(BookingStatus status) { this.status = status; } - - public LocalDateTime getCreatedAt() { return createdAt; } - public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } - - // ---------------------------- - // Inner class Extra - // ---------------------------- - @Entity - public static class Extra { - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String name; - private double price; - - protected Extra() {} - - public Extra(String name, double price) { - this.name = name; - this.price = price; - } - - public Long getId() { return id; } - public String getName() { return name; } - public void setName(String name) { this.name = name; } - public double getPrice() { return price; } - public void setPrice(double price) { this.price = price; } - } } - diff --git a/src/main/java/org/example/model/Car.java b/src/main/java/org/example/model/Car.java index 27bb15d7..5aa518c8 100644 --- a/src/main/java/org/example/model/Car.java +++ b/src/main/java/org/example/model/Car.java @@ -1,12 +1,12 @@ package org.example.model; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; +import jakarta.persistence.*; +import java.util.ArrayList; +import java.util.List; @Entity public class Car { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @@ -14,28 +14,41 @@ public class Car { private String brand; private String model; private int year; - private String type; - private double price; - private double dailyPrice; // ny egenskap - // Getters och setters + @Enumerated(EnumType.STRING) + private CarType type; + private double dailyPrice; + private boolean available = true; + private boolean damaged = false; + + public Car() {} + public Car(String brand, String model, int year, CarType type, double dailyPrice) { + this.brand = brand; + this.model = model; + this.year = year; + this.type = type; + this.dailyPrice = dailyPrice; + } + + // Getters som krävs för TableView (PropertyValueFactory) public Long getId() { return id; } - public String getBrand() { return brand; } - public void setBrand(String brand) { this.brand = brand; } - public String getModel() { return model; } - public void setModel(String model) { this.model = model; } - public int getYear() { return year; } - public void setYear(int year) { this.year = year; } - - public String getType() { return type; } - public void setType(String type) { this.type = type; } + public CarType getType() { return type; } + public double getDailyPrice() { return dailyPrice; } + public boolean isAvailable() { return available; } + public boolean isDamaged() { return damaged; } - public double getPrice() { return price; } - public void setPrice(double price) { this.price = price; } + // Setters + public void setAvailable(boolean available) { this.available = available; } + public void setDamaged(boolean damaged) { this.damaged = damaged; } - public double getDailyPrice() { return dailyPrice; } - public void setDailyPrice(double dailyPrice) { this.dailyPrice = dailyPrice; } + @Override + public String toString() { + return brand + " " + model + " (" + year + ") - " + dailyPrice + " kr/dag"; + } } + + + diff --git a/src/main/java/org/example/model/CarType.java b/src/main/java/org/example/model/CarType.java new file mode 100644 index 00000000..50f4a990 --- /dev/null +++ b/src/main/java/org/example/model/CarType.java @@ -0,0 +1,8 @@ +package org.example.model; + +public enum CarType { + SMALL, + FAMILY, + VAN, + SPORT +} diff --git a/src/main/java/org/example/model/Customer.java b/src/main/java/org/example/model/Customer.java index 1a66e22d..79ed55d3 100644 --- a/src/main/java/org/example/model/Customer.java +++ b/src/main/java/org/example/model/Customer.java @@ -8,14 +8,64 @@ public class Customer { @Id - @GeneratedValue + @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String name; + private String firstName; + private String lastName; private String email; + // -------- One-to-Many -------- @OneToMany(mappedBy = "customer") private List bookings = new ArrayList<>(); - // getters & setters + // -------- Constructors -------- + protected Customer() { + // JPA kräver tom konstruktor + } + + public Customer(String firstName, String lastName, String email) { + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + } + + // -------- Getters & setters -------- + public Long getId() { + return id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public List getBookings() { + return bookings; + } + + // -------- Nice to have -------- + @Override + public String toString() { + return firstName + " " + lastName + " (" + email + ")"; + } } diff --git a/src/main/java/org/example/model/Extra.java b/src/main/java/org/example/model/Extra.java index 6a6b87a9..016a8fb7 100644 --- a/src/main/java/org/example/model/Extra.java +++ b/src/main/java/org/example/model/Extra.java @@ -1,19 +1,31 @@ package org.example.model; +import jakarta.persistence.*; +import java.util.ArrayList; +import java.util.List; + +@Entity public class Extra { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private String name; private double price; - // Konstruktor + @ManyToMany(mappedBy = "extras") + private List bookings = new ArrayList<>(); + + public Extra() {} + public Extra(String name, double price) { this.name = name; this.price = price; } - // Getters och setters - public String getName() { return name; } - public void setName(String name) { this.name = name; } - public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } + public String getName() { return name; } } + diff --git a/src/main/java/org/example/repository/BookingRepository.java b/src/main/java/org/example/repository/BookingRepository.java index a63b50d4..6baa468e 100644 --- a/src/main/java/org/example/repository/BookingRepository.java +++ b/src/main/java/org/example/repository/BookingRepository.java @@ -1,4 +1,33 @@ package org.example.repository; +import org.example.model.Booking; +import jakarta.persistence.EntityManager; +import org.example.util.JPAUtil; +import java.util.List; + public class BookingRepository { + + public void save(Booking booking) { + EntityManager em = JPAUtil.getEntityManager(); + try { + em.getTransaction().begin(); + if (booking.getId() == null) { + em.persist(booking); + } else { + em.merge(booking); + } + em.getTransaction().commit(); + } catch (Exception e) { + if (em.getTransaction().isActive()) em.getTransaction().rollback(); + throw e; + } finally { + em.close(); + } + } + + public List findAll() { + try (EntityManager em = JPAUtil.getEntityManager()) { + return em.createQuery("SELECT b FROM Booking b", Booking.class).getResultList(); + } + } } diff --git a/src/main/java/org/example/repository/CarRepository.java b/src/main/java/org/example/repository/CarRepository.java index d4f473ab..77237737 100644 --- a/src/main/java/org/example/repository/CarRepository.java +++ b/src/main/java/org/example/repository/CarRepository.java @@ -1,21 +1,37 @@ package org.example.repository; import org.example.model.Car; - import jakarta.persistence.EntityManager; -import java.util.List; import org.example.util.JPAUtil; +import java.util.List; public class CarRepository { public List findAll() { - EntityManager em = JPAUtil.getEntityManager(); + try (EntityManager em = JPAUtil.getEntityManager()) { + return em.createQuery("SELECT c FROM Car c", Car.class).getResultList(); + } + } - List cars = - em.createQuery("SELECT c FROM Car c", Car.class) - .getResultList(); + public List findAvailableCars() { + try (EntityManager em = JPAUtil.getEntityManager()) { + return em.createQuery("SELECT c FROM Car c WHERE c.available = true AND c.damaged = false", Car.class) + .getResultList(); + } + } - em.close(); - return cars; + public void save(Car car) { + EntityManager em = JPAUtil.getEntityManager(); + try { + em.getTransaction().begin(); + if (car.getId() == null) { + em.persist(car); + } else { + em.merge(car); + } + em.getTransaction().commit(); + } finally { + em.close(); + } } } diff --git a/src/main/java/org/example/repository/CustomerRepository.java b/src/main/java/org/example/repository/CustomerRepository.java index 38b788c2..36c35862 100644 --- a/src/main/java/org/example/repository/CustomerRepository.java +++ b/src/main/java/org/example/repository/CustomerRepository.java @@ -1,4 +1,41 @@ + package org.example.repository; +import org.example.model.Customer; +import jakarta.persistence.EntityManager; +import org.example.util.JPAUtil; +import java.util.List; +import java.util.Optional; + public class CustomerRepository { + + public void save(Customer customer) { + EntityManager em = JPAUtil.getEntityManager(); + try { + em.getTransaction().begin(); + if (customer.getId() == null) { + em.persist(customer); + } else { + em.merge(customer); + } + em.getTransaction().commit(); + } finally { + em.close(); + } + } + + public Optional findByEmail(String email) { + try (EntityManager em = JPAUtil.getEntityManager()) { + return em.createQuery("SELECT c FROM Customer c WHERE c.email = :email", Customer.class) + .setParameter("email", email) + .getResultStream() + .findFirst(); + } + } + + public List findAll() { + try (EntityManager em = JPAUtil.getEntityManager()) { + return em.createQuery("SELECT c FROM Customer c", Customer.class).getResultList(); + } + } } diff --git a/src/main/java/org/example/service/BookingService.java b/src/main/java/org/example/service/BookingService.java index aea99093..2957b158 100644 --- a/src/main/java/org/example/service/BookingService.java +++ b/src/main/java/org/example/service/BookingService.java @@ -1,4 +1,46 @@ package org.example.service; +import org.example.model.Booking; +import org.example.model.BookingStatus; +import org.example.model.Extra; +import org.example.repository.BookingRepository; +import org.example.repository.CarRepository; +import java.util.List; + public class BookingService { + + private final BookingRepository bookingRepository = new BookingRepository(); + private final CarRepository carRepository = new CarRepository(); + + public double calculateTotalPrice(Booking booking) { + if (booking.getCar() == null) return 0.0; + + long days = booking.getDurationInDays(); + if (days <= 0) days = 1; + + double carTotal = booking.getCar().getDailyPrice() * days; + double extrasTotal = booking.getExtras().stream() + .mapToDouble(Extra::getPrice) + .sum(); + + return carTotal + extrasTotal; + } + + public void createBooking(Booking booking) { + if (booking.getCar() == null || !booking.getCar().isAvailable()) { + throw new IllegalStateException("Bilen är inte tillgänglig för bokning."); + } + + // Sätt status och spara + booking.setStatus(BookingStatus.RESERVED); + bookingRepository.save(booking); + + // Uppdatera bilens status så den inte kan bokas av någon annan + booking.getCar().setAvailable(false); + carRepository.save(booking.getCar()); + } + + public List getAllBookings() { + return bookingRepository.findAll(); + } } diff --git a/src/main/java/org/example/service/CarService.java b/src/main/java/org/example/service/CarService.java index e81e1ea5..fee0ef7b 100644 --- a/src/main/java/org/example/service/CarService.java +++ b/src/main/java/org/example/service/CarService.java @@ -1,4 +1,29 @@ package org.example.service; +import org.example.model.Car; +import org.example.repository.CarRepository; +import java.util.List; + public class CarService { + + private final CarRepository carRepository = new CarRepository(); + + public List getAllCars() { + return carRepository.findAll(); + } + + public List getAvailableCars() { + return carRepository.findAvailableCars(); + } + + public void markAsDamaged(Car car) { + car.setDamaged(true); + car.setAvailable(false); + carRepository.save(car); + } + + public void updateCarStatus(Car car, boolean available) { + car.setAvailable(available); + carRepository.save(car); + } } diff --git a/src/main/java/org/example/service/CustomerService.java b/src/main/java/org/example/service/CustomerService.java index 4c00baea..436ff3a3 100644 --- a/src/main/java/org/example/service/CustomerService.java +++ b/src/main/java/org/example/service/CustomerService.java @@ -1,4 +1,29 @@ package org.example.service; +import org.example.model.Customer; +import org.example.repository.CustomerRepository; +import java.util.List; +import java.util.Optional; + public class CustomerService { + + private final CustomerRepository customerRepository = new CustomerRepository(); + + public void saveCustomer(Customer customer) { + // Validering: kolla om e-post redan finns + Optional existing = customerRepository.findByEmail(customer.getEmail()); + if (existing.isPresent()) { + System.out.println("Kunden finns redan i systemet."); + return; + } + customerRepository.save(customer); + } + + public List getAllCustomers() { + return customerRepository.findAll(); + } + + public Optional findCustomerByEmail(String email) { + return customerRepository.findByEmail(email); + } } diff --git a/src/main/java/org/example/util/DataInitializer.java b/src/main/java/org/example/util/DataInitializer.java new file mode 100644 index 00000000..9bdf24fe --- /dev/null +++ b/src/main/java/org/example/util/DataInitializer.java @@ -0,0 +1,53 @@ +package org.example.util; + +import jakarta.persistence.EntityManager; +import org.example.model.*; + +public class DataInitializer { + + public static void seed(EntityManager em) { + + + if (!em.createQuery("SELECT c FROM Car c").getResultList().isEmpty()) { + return; + } + + em.getTransaction().begin(); + + // ---------------- Cars (20 st) ---------------- + em.persist(new Car("Volkswagen", "Polo", 2022, CarType.SMALL, 399)); + em.persist(new Car("Toyota", "Yaris", 2023, CarType.SMALL, 429)); + em.persist(new Car("Hyundai", "i20", 2021, CarType.SMALL, 389)); + em.persist(new Car("Kia", "Rio", 2022, CarType.SMALL, 399)); + + em.persist(new Car("Volvo", "V60", 2023, CarType.FAMILY, 699)); + em.persist(new Car("Volkswagen", "Passat", 2022, CarType.FAMILY, 649)); + em.persist(new Car("Skoda", "Octavia", 2023, CarType.FAMILY, 629)); + em.persist(new Car("Toyota", "Corolla Touring", 2022, CarType.FAMILY, 619)); + + em.persist(new Car("Volkswagen", "Transporter", 2021, CarType.VAN, 899)); + em.persist(new Car("Ford", "Transit", 2022, CarType.VAN, 949)); + em.persist(new Car("Mercedes", "Vito", 2023, CarType.VAN, 999)); + em.persist(new Car("Renault", "Trafic", 2021, CarType.VAN, 879)); + + em.persist(new Car("BMW", "M3", 2023, CarType.SPORT, 1999)); + em.persist(new Car("Audi", "RS5", 2022, CarType.SPORT, 1899)); + em.persist(new Car("Porsche", "911", 2023, CarType.SPORT, 2999)); + em.persist(new Car("Mercedes", "AMG GT", 2022, CarType.SPORT, 2799)); + + em.persist(new Car("Mazda", "CX-5", 2022, CarType.FAMILY, 679)); + em.persist(new Car("Tesla", "Model Y", 2023, CarType.FAMILY, 799)); + em.persist(new Car("Mini", "Cooper", 2022, CarType.SMALL, 459)); + em.persist(new Car("Seat", "Leon", 2023, CarType.FAMILY, 599)); + + // ---------------- Extras ---------------- + em.persist(new Extra("Försäkring", 149)); + em.persist(new Extra("Takbox", 99)); + em.persist(new Extra("GPS", 59)); + em.persist(new Extra("Barnstol", 79)); + + em.getTransaction().commit(); + + System.out.println(" Seed-data skapad (20 bilar + extras)"); + } +} diff --git a/src/main/java/org/example/util/JPAUtil.java b/src/main/java/org/example/util/JPAUtil.java index df1f9b38..f5a56eb7 100644 --- a/src/main/java/org/example/util/JPAUtil.java +++ b/src/main/java/org/example/util/JPAUtil.java @@ -8,7 +8,17 @@ public class JPAUtil { private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("carRentalPU"); + public static EntityManagerFactory getEntityManagerFactory() { + return emf; + } + public static EntityManager getEntityManager() { return emf.createEntityManager(); } + + public static void shutdown() { + if (emf != null && emf.isOpen()) { + emf.close(); + } + } } diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml index 9abd48a0..969450a8 100644 --- a/src/main/resources/META-INF/persistence.xml +++ b/src/main/resources/META-INF/persistence.xml @@ -1,23 +1,32 @@ + - + + org.hibernate.jpa.HibernatePersistenceProvider + + org.example.model.Car - + org.example.model.Customer + org.example.model.Booking + org.example.model.Extra + org.example.model.Location + org.example.model.Payment - - - - + + + + + - + + + + - diff --git a/src/main/resources/css/main.css b/src/main/resources/css/main.css index 90bc399a..342d5100 100644 --- a/src/main/resources/css/main.css +++ b/src/main/resources/css/main.css @@ -1,3 +1,130 @@ -tabell med bilar -uthyrnings tabell med many2man -kund tabell +/* Färgtema: Midnight Gold */ +.main-container { + -fx-background-color: #f4f7f6; +} + +.sidebar { + -fx-background-color: #1a2a3a; /* Mörk marinblå */ +} + +.logo-text { + -fx-text-fill: #ffcc00; /* Guld/Gul */ + -fx-margin-bottom: 20; +} + +.nav-button { + -fx-background-color: transparent; + -fx-text-fill: #ffffff; + -fx-alignment: CENTER_LEFT; + -fx-font-size: 14px; + -fx-cursor: hand; + -fx-padding: 10 15; + -fx-border-radius: 5; +} + +.nav-button:hover { + -fx-background-color: #2c3e50; + -fx-text-fill: #ffcc00; +} + +.welcome-header { + -fx-font-size: 32px; + -fx-font-weight: bold; + -fx-text-fill: #1a2a3a; +} + +.welcome-subtext { + -fx-font-size: 16px; + -fx-text-fill: #7f8c8d; +} + +.content-pane { + -fx-background-color: white; + -fx-background-radius: 10 0 0 10; + -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.1), 10, 0, 0, 0); +} + +.view-header { + -fx-font-size: 28px; + -fx-font-weight: bold; + -fx-text-fill: #1a2a3a; +} + +.view-subheader { + -fx-font-size: 14px; + -fx-text-fill: #7f8c8d; +} + +.search-field { + -fx-background-radius: 20; + -fx-padding: 8 15; + -fx-border-color: #dcdde1; + -fx-border-radius: 20; +} + +.modern-table { + -fx-background-color: transparent; + -fx-border-color: #dcdde1; + -fx-border-radius: 5; +} + +.modern-table .column-header { + -fx-background-color: #f8f9fa; + -fx-padding: 10; +} + +.primary-button { + -fx-background-color: #ffcc00; /* Guld */ + -fx-text-fill: #1a2a3a; + -fx-font-weight: bold; + -fx-padding: 10 25; + -fx-background-radius: 5; + -fx-cursor: hand; +} + +.primary-button:hover { + -fx-background-color: #e6b800; +} + +.secondary-button { + -fx-background-color: transparent; + -fx-border-color: #1a2a3a; + -fx-text-fill: #1a2a3a; + -fx-padding: 10 25; + -fx-background-radius: 5; + -fx-cursor: hand; +} + +.summary-pane { + -fx-background-color: #f8f9fa; + -fx-border-color: #dcdde1; + -fx-border-radius: 10; + -fx-background-radius: 10; +} + +.summary-header { + -fx-font-size: 18px; + -fx-font-weight: bold; + -fx-text-fill: #1a2a3a; +} + +.total-label { + -fx-font-weight: bold; + -fx-font-size: 14px; +} + +.total-price { + -fx-font-size: 22px; + -fx-font-weight: bold; + -fx-text-fill: #1a2a3a; +} + +.section-header { + -fx-font-size: 16px; + -fx-font-weight: bold; + -fx-padding: 10 0; +} + +.bold-text { + -fx-font-weight: bold; +} diff --git a/src/main/resources/fxml/booking_view.fxml b/src/main/resources/fxml/booking_view.fxml index e69de29b..5c106095 100644 --- a/src/main/resources/fxml/booking_view.fxml +++ b/src/main/resources/fxml/booking_view.fxml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + +