diff --git a/.env b/.env
new file mode 100644
index 0000000..18edda9
--- /dev/null
+++ b/.env
@@ -0,0 +1,8 @@
+MYSQLDB_DATABASE=air_companies_management
+MYSQLDB_USER=root
+MYSQLDB_ROOT_PASSWORD=default
+MYSQLDB_LOCAL_PORT=3308
+MYSQLDB_DOCKER_PORT=3306
+SPRING_LOCAL_PORT=8088
+SPRING_DOCKER_PORT=8080
+DEBUG_PORT=5005
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..282f50a
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,18 @@
+name: Java CI
+
+on: [push, pull_request]
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Set up JDK 17
+ uses: actions/setup-java@v2
+ with:
+ java-version: '17'
+ distribution: 'adopt'
+ cache: maven
+ - name: Build with Maven
+ run: mvn --batch-mode --update-snapshots verify
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5c8ebe8
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,14 @@
+FROM openjdk:11 as builder
+WORKDIR application
+ARG JAR_FILE=target/*.jar
+COPY ${JAR_FILE} application.jar
+RUN java -Djarmode=layertools -jar application.jar extract
+
+FROM openjdk:11
+WORKDIR application
+COPY --from=builder application/dependencies/ ./
+COPY --from=builder application/spring-boot-loader/ ./
+COPY --from=builder application/snapshot-dependencies/ ./
+COPY --from=builder application/application/ ./
+ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"]
+EXPOSE 8080
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..ea0a529
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,250 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..b0bd32a
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,37 @@
+version: "3.8"
+
+services:
+ mysqldb:
+ platform: linux/arm64
+ image: mysql:latest
+ restart: unless-stopped
+ env_file: ./.env
+ environment:
+ - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD
+ - MYSQL_DATABASE=$MYSQLDB_DATABASE
+ ports:
+ - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT
+ healthcheck:
+ test: [ "CMD", "mysqladmin" ,"ping", "-h", "localhost" ]
+ timeout: 30s
+ retries: 3
+ app:
+ depends_on:
+ mysqldb:
+ condition: service_healthy
+ restart: on-failure
+ image: air_companies_management
+ build: .
+ env_file: ./.env
+ ports:
+ - $SPRING_LOCAL_PORT:$SPRING_DOCKER_PORT
+ - $DEBUG_PORT:$DEBUG_PORT
+ environment:
+ SPRING_APPLICATION_JSON: '{
+ "spring.datasource.url" : "jdbc:mysql://mysqldb:$MYSQLDB_DOCKER_PORT/$MYSQLDB_DATABASE",
+ "spring.datasource.username" : "$MYSQLDB_USER",
+ "spring.datasource.password" : "$MYSQLDB_ROOT_PASSWORD",
+ "spring.datasource.driver-class-name" : "com.mysql.cj.jdbc.Driver",
+ "spring.jpa.hibernate.ddl-auto" : "create-drop"
+ }'
+ JAVA_TOOL_OPTIONS: "-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005"
diff --git a/pom.xml b/pom.xml
index c595abd..71a2f77 100644
--- a/pom.xml
+++ b/pom.xml
@@ -15,12 +15,59 @@
Demo project for Spring Boot
11
+ 2.2.13.RELEASE
+ 3.3.0
+ 3.8.1
+ checkstyle.xml
+ 8.0.33
+ 0.2.0
+ 1.5.5.Final
+ 1.18.32
+ 1.8.0
org.springframework.boot
spring-boot-starter
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ mysql
+ mysql-connector-java
+ ${mysql.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+ true
+
+
+ org.mapstruct
+ mapstruct
+ ${mapstruct.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ ${lombok.mapstruct.binding.version}
+
+
+ org.springdoc
+ springdoc-openapi-ui
+ ${openapi.version}
+
org.springframework.boot
@@ -34,6 +81,53 @@
org.springframework.boot
spring-boot-maven-plugin
+ ${spring.boot.version}
+
+
+ org.apache.maven.plugins
+ maven-checkstyle-plugin
+ ${maven.checkstyle.plugin.version}
+
+
+ compile
+
+ check
+
+
+
+
+ ${maven.checkstyle.plugin.configLocation}
+ true
+ true
+ false
+ src
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${maven.compiler.plugin.version}
+
+
+ ${java.version}
+
+
+ org.projectlombok
+ lombok
+ ${lombok.version}
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ ${lombok.mapstruct.binding.version}
+
+
+ org.mapstruct
+ mapstruct-processor
+ ${mapstruct.version}
+
+
+
diff --git a/src/main/java/org/company/aircompaniesmanager/AirCompaniesManagerApplication.java b/src/main/java/org/company/aircompaniesmanager/AirCompaniesManagerApplication.java
index 986a453..8690485 100644
--- a/src/main/java/org/company/aircompaniesmanager/AirCompaniesManagerApplication.java
+++ b/src/main/java/org/company/aircompaniesmanager/AirCompaniesManagerApplication.java
@@ -5,9 +5,7 @@
@SpringBootApplication
public class AirCompaniesManagerApplication {
-
- public static void main(String[] args) {
- SpringApplication.run(AirCompaniesManagerApplication.class, args);
- }
-
+ public static void main(String[] args) {
+ SpringApplication.run(AirCompaniesManagerApplication.class, args);
+ }
}
diff --git a/src/main/java/org/company/aircompaniesmanager/config/MapperConfig.java b/src/main/java/org/company/aircompaniesmanager/config/MapperConfig.java
new file mode 100644
index 0000000..650b446
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/config/MapperConfig.java
@@ -0,0 +1,13 @@
+package org.company.aircompaniesmanager.config;
+
+import org.mapstruct.InjectionStrategy;
+import org.mapstruct.NullValueCheckStrategy;
+
+@org.mapstruct.MapperConfig(
+ componentModel = "spring",
+ injectionStrategy = InjectionStrategy.CONSTRUCTOR,
+ nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS,
+ implementationPackage = ".impl"
+)
+public class MapperConfig {
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/controller/AirCompanyController.java b/src/main/java/org/company/aircompaniesmanager/controller/AirCompanyController.java
new file mode 100644
index 0000000..0ffc47b
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/controller/AirCompanyController.java
@@ -0,0 +1,70 @@
+package org.company.aircompaniesmanager.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import javax.validation.Valid;
+import lombok.RequiredArgsConstructor;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyRequestDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyResponseDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyUpdateRequestDto;
+import org.company.aircompaniesmanager.service.air.company.AirCompanyService;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/air-companies")
+@Tag(
+ name = "Air companies management",
+ description = "Endpoints for managing air companies"
+)
+public class AirCompanyController {
+ private final AirCompanyService airCompanyService;
+
+ @GetMapping
+ @Operation(summary = "Find all air companies",
+ description = "Retrieves detailed information about all companies")
+ private List findAll(Pageable pageable) {
+ return airCompanyService.findAll(pageable);
+ }
+
+ @GetMapping("/{id}")
+ @Operation(summary = "Find air company by id",
+ description = "Retrieves detailed information about specified company")
+ private AirCompanyResponseDto findById(@PathVariable Long id) {
+ return airCompanyService.findById(id);
+ }
+
+ @PostMapping
+ @Operation(summary = "Save air company",
+ description = "Creates new company")
+ private AirCompanyResponseDto save(@RequestBody @Valid AirCompanyRequestDto requestDto) {
+ return airCompanyService.save(requestDto);
+ }
+
+ @PutMapping("/{id}")
+ @Operation(summary = "Update air company",
+ description = "Updates information about company type")
+ private AirCompanyResponseDto updateById(
+ @PathVariable Long id,
+ @RequestBody @Valid AirCompanyUpdateRequestDto requestDto
+ ) {
+ return airCompanyService.updateById(id, requestDto);
+ }
+
+ @DeleteMapping("/{id}")
+ @Operation(summary = "Delete air company",
+ description = "Removes air company")
+ private String deleteById(@PathVariable Long id) {
+ airCompanyService.deleteById(id);
+ return String.format("Company with id: '%s' deleted successfully.", id);
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/controller/AirplaneController.java b/src/main/java/org/company/aircompaniesmanager/controller/AirplaneController.java
new file mode 100644
index 0000000..57ae203
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/controller/AirplaneController.java
@@ -0,0 +1,60 @@
+package org.company.aircompaniesmanager.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneRequestDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneResponseDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneUpdateRequestDto;
+import org.company.aircompaniesmanager.service.airplane.AirplaneService;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/airplanes")
+@Tag(
+ name = "Airplanes management",
+ description = "Endpoints for managing airplanes"
+)
+public class AirplaneController {
+ private final AirplaneService airplaneService;
+
+ @GetMapping
+ @Operation(summary = "Find all airplanes",
+ description = "Retrieves detailed information about all airplanes")
+ public List findAll(Pageable pageable) {
+ return airplaneService.findAll(pageable);
+ }
+
+ @GetMapping("/{id}")
+ @Operation(summary = "Find airplane by id",
+ description = "Retrieves detailed information about specified airplane")
+ public AirplaneResponseDto findById(@PathVariable Long id) {
+ return airplaneService.findById(id);
+ }
+
+ @PostMapping
+ @Operation(summary = "Save new airplane",
+ description = "Creates new airplane")
+ public AirplaneResponseDto save(@RequestBody AirplaneRequestDto requestDto) {
+ return airplaneService.save(requestDto);
+ }
+
+ @PutMapping("/{id}")
+ @Operation(summary = "Reassign to another company",
+ description = "Updates airplane company")
+ public AirplaneResponseDto updateCompany(
+ @PathVariable Long id,
+ @RequestBody AirplaneUpdateRequestDto requestDto
+ ) {
+ return airplaneService.updateCompany(id, requestDto);
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/controller/FlightController.java b/src/main/java/org/company/aircompaniesmanager/controller/FlightController.java
new file mode 100644
index 0000000..2d861f6
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/controller/FlightController.java
@@ -0,0 +1,95 @@
+package org.company.aircompaniesmanager.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import java.util.List;
+import lombok.RequiredArgsConstructor;
+import org.company.aircompaniesmanager.dto.flight.FlightRequestDto;
+import org.company.aircompaniesmanager.dto.flight.FlightResponseDto;
+import org.company.aircompaniesmanager.dto.flight.FlightUpdateRequestDto;
+import org.company.aircompaniesmanager.service.flight.FlightService;
+import org.springframework.data.domain.Pageable;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/flights")
+@Tag(
+ name = "Flights management",
+ description = "Endpoints for managing flights"
+)
+public class FlightController {
+ private final FlightService flightService;
+
+ @GetMapping
+ @Operation(summary = "Find all flights",
+ description = "Retrieves detailed information about all flights")
+ List findAll(Pageable pageable) {
+ return flightService.findAll(pageable);
+ }
+
+ @GetMapping("/expired")
+ @Operation(
+ summary = "Find flights with active status and expired time",
+ description = "Retrieves detailed information "
+ + "about flights by specified status with specified status"
+ )
+ List findAllExpired(Pageable pageable) {
+ return flightService.findAllExpired(pageable);
+ }
+
+ @GetMapping("/overdue")
+ @Operation(
+ summary = "Find flights with completed status and overdue time",
+ description = "Retrieves detailed information "
+ + "about flights by completed status with overdue time"
+ )
+ List findAllOverdue(Pageable pageable) {
+ return flightService.findAllOverdue(pageable);
+ }
+
+ @GetMapping("/{status}/company")
+ @Operation(
+ summary = "Find flight by status and company",
+ description = "Retrieves detailed information "
+ + "about flights by specified company with specified status"
+ )
+ List findAllByCompanyNameAndStatus(
+ @RequestParam String name,
+ @PathVariable String status,
+ Pageable pageable
+ ) {
+ return flightService.findAllByCompanyName(name, status, pageable);
+ }
+
+ @GetMapping("/{id}")
+ @Operation(summary = "Find flight by id",
+ description = "Retrieves detailed information about specified flight")
+ FlightResponseDto findById(@PathVariable Long id) {
+ return flightService.findById(id);
+ }
+
+ @PostMapping
+ @Operation(summary = "Save new flight",
+ description = "Creates new flight")
+ FlightResponseDto save(@RequestBody FlightRequestDto requestDto) {
+ return flightService.save(requestDto);
+ }
+
+ @PutMapping("/{id}")
+ @Operation(summary = "Update flight status",
+ description = "Updates status in specified flight")
+ FlightResponseDto updateStatus(
+ @PathVariable Long id,
+ @RequestBody FlightUpdateRequestDto requestDto
+ ) {
+ return flightService.updateStatus(id, requestDto);
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/controller/HealthController.java b/src/main/java/org/company/aircompaniesmanager/controller/HealthController.java
new file mode 100644
index 0000000..76d8c42
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/controller/HealthController.java
@@ -0,0 +1,12 @@
+package org.company.aircompaniesmanager.controller;
+
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+public class HealthController {
+ @GetMapping("/health")
+ public String getHealth() {
+ return "Server is working...";
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyRequestDto.java b/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyRequestDto.java
new file mode 100644
index 0000000..dce63b7
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyRequestDto.java
@@ -0,0 +1,16 @@
+package org.company.aircompaniesmanager.dto.air.company;
+
+import java.time.LocalDate;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import lombok.Data;
+
+@Data
+public class AirCompanyRequestDto {
+ @NotBlank
+ private String name;
+ @NotBlank
+ private String companyType;
+ @NotNull
+ private LocalDate foundationDate;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyResponseDto.java b/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyResponseDto.java
new file mode 100644
index 0000000..8993676
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyResponseDto.java
@@ -0,0 +1,12 @@
+package org.company.aircompaniesmanager.dto.air.company;
+
+import java.time.LocalDate;
+import lombok.Data;
+
+@Data
+public class AirCompanyResponseDto {
+ private Long id;
+ private String name;
+ private String companyType;
+ private LocalDate foundationDate;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyUpdateRequestDto.java b/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyUpdateRequestDto.java
new file mode 100644
index 0000000..837b097
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/air/company/AirCompanyUpdateRequestDto.java
@@ -0,0 +1,10 @@
+package org.company.aircompaniesmanager.dto.air.company;
+
+import javax.validation.constraints.NotBlank;
+import lombok.Data;
+
+@Data
+public class AirCompanyUpdateRequestDto {
+ @NotBlank
+ private String companyType;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneRequestDto.java b/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneRequestDto.java
new file mode 100644
index 0000000..88ee116
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneRequestDto.java
@@ -0,0 +1,28 @@
+package org.company.aircompaniesmanager.dto.airplane;
+
+import java.time.LocalDate;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
+import lombok.Data;
+
+@Data
+public class AirplaneRequestDto {
+ @NotBlank
+ private String factorySerialNumber;
+ @Positive
+ private Long airCompanyId;
+ @Positive
+ @NotNull
+ private int numberOfFlights;
+ @Positive
+ @NotNull
+ private double flightDistance;
+ @Positive
+ @NotNull
+ private double fuelCapacity;
+ @NotBlank
+ private String type;
+ @NotNull
+ private LocalDate creationDate;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneResponseDto.java b/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneResponseDto.java
new file mode 100644
index 0000000..0ff9a85
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneResponseDto.java
@@ -0,0 +1,16 @@
+package org.company.aircompaniesmanager.dto.airplane;
+
+import java.time.LocalDate;
+import lombok.Data;
+
+@Data
+public class AirplaneResponseDto {
+ private Long id;
+ private String factorySerialNumber;
+ private Long airCompanyId;
+ private int numberOfFlights;
+ private double flightDistance;
+ private double fuelCapacity;
+ private String type;
+ private LocalDate creationDate;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneUpdateRequestDto.java b/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneUpdateRequestDto.java
new file mode 100644
index 0000000..ea8f354
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/airplane/AirplaneUpdateRequestDto.java
@@ -0,0 +1,12 @@
+package org.company.aircompaniesmanager.dto.airplane;
+
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
+import lombok.Data;
+
+@Data
+public class AirplaneUpdateRequestDto {
+ @NotNull
+ @Positive
+ private Long airCompanyId;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightRequestDto.java b/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightRequestDto.java
new file mode 100644
index 0000000..b07871d
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightRequestDto.java
@@ -0,0 +1,32 @@
+package org.company.aircompaniesmanager.dto.flight;
+
+import java.time.LocalDateTime;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Positive;
+import lombok.Data;
+
+@Data
+public class FlightRequestDto {
+ @NotNull
+ @Positive
+ private Long airCompanyId;
+ @NotNull
+ @Positive
+ private Long airplaneId;
+ @NotBlank
+ private String departureCountry;
+ @NotBlank
+ private String destinationCountry;
+ @NotNull
+ @Positive
+ private double distance;
+ // Estimated time in hours
+ @NotNull
+ @Positive
+ private double estimatedTime;
+ private LocalDateTime startTime;
+ private LocalDateTime endTime;
+ private LocalDateTime delayStartTime;
+ private LocalDateTime creationDate;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightResponseDto.java b/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightResponseDto.java
new file mode 100644
index 0000000..8b9bc23
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightResponseDto.java
@@ -0,0 +1,21 @@
+package org.company.aircompaniesmanager.dto.flight;
+
+import java.time.LocalDateTime;
+import lombok.Data;
+import org.company.aircompaniesmanager.model.Flight.Status;
+
+@Data
+public class FlightResponseDto {
+ private Long id;
+ private Status status;
+ private Long airCompanyId;
+ private Long airplaneId;
+ private String departureCountry;
+ private String destinationCountry;
+ private double distance;
+ private double estimatedTime;
+ private LocalDateTime startTime;
+ private LocalDateTime endTime;
+ private LocalDateTime delayStartTime;
+ private LocalDateTime creationDate;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightUpdateRequestDto.java b/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightUpdateRequestDto.java
new file mode 100644
index 0000000..f68b2ba
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/dto/flight/FlightUpdateRequestDto.java
@@ -0,0 +1,11 @@
+package org.company.aircompaniesmanager.dto.flight;
+
+import javax.validation.constraints.NotBlank;
+import lombok.Data;
+import org.company.aircompaniesmanager.model.Flight.Status;
+
+@Data
+public class FlightUpdateRequestDto {
+ @NotBlank
+ private Status status;
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/exception/EntityNotFoundException.java b/src/main/java/org/company/aircompaniesmanager/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..49d20c8
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/exception/EntityNotFoundException.java
@@ -0,0 +1,7 @@
+package org.company.aircompaniesmanager.exception;
+
+public class EntityNotFoundException extends RuntimeException {
+ public EntityNotFoundException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/mapper/AirCompanyMapper.java b/src/main/java/org/company/aircompaniesmanager/mapper/AirCompanyMapper.java
new file mode 100644
index 0000000..f9a326d
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/mapper/AirCompanyMapper.java
@@ -0,0 +1,14 @@
+package org.company.aircompaniesmanager.mapper;
+
+import org.company.aircompaniesmanager.config.MapperConfig;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyRequestDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyResponseDto;
+import org.company.aircompaniesmanager.model.AirCompany;
+import org.mapstruct.Mapper;
+
+@Mapper(config = MapperConfig.class)
+public interface AirCompanyMapper {
+ AirCompanyResponseDto toDto(AirCompany airCompany);
+
+ AirCompany toEntity(AirCompanyRequestDto requestDto);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/mapper/AirplaneMapper.java b/src/main/java/org/company/aircompaniesmanager/mapper/AirplaneMapper.java
new file mode 100644
index 0000000..9a4b866
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/mapper/AirplaneMapper.java
@@ -0,0 +1,16 @@
+package org.company.aircompaniesmanager.mapper;
+
+import org.company.aircompaniesmanager.config.MapperConfig;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneRequestDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneResponseDto;
+import org.company.aircompaniesmanager.model.Airplane;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+
+@Mapper(config = MapperConfig.class)
+public interface AirplaneMapper {
+ @Mapping(target = "airCompanyId", source = "airCompany.id")
+ AirplaneResponseDto toDto(Airplane airplane);
+
+ Airplane toEntity(AirplaneRequestDto requestDto);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/mapper/FlightMapper.java b/src/main/java/org/company/aircompaniesmanager/mapper/FlightMapper.java
new file mode 100644
index 0000000..9ca83a7
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/mapper/FlightMapper.java
@@ -0,0 +1,17 @@
+package org.company.aircompaniesmanager.mapper;
+
+import org.company.aircompaniesmanager.config.MapperConfig;
+import org.company.aircompaniesmanager.dto.flight.FlightRequestDto;
+import org.company.aircompaniesmanager.dto.flight.FlightResponseDto;
+import org.company.aircompaniesmanager.model.Flight;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+
+@Mapper(config = MapperConfig.class)
+public interface FlightMapper {
+ @Mapping(target = "airplaneId", source = "airplane.id")
+ @Mapping(target = "airCompanyId", source = "airCompany.id")
+ FlightResponseDto toDto(Flight flight);
+
+ Flight toEntity(FlightRequestDto requestDto);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/model/AirCompany.java b/src/main/java/org/company/aircompaniesmanager/model/AirCompany.java
new file mode 100644
index 0000000..1b0e842
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/model/AirCompany.java
@@ -0,0 +1,38 @@
+package org.company.aircompaniesmanager.model;
+
+import java.time.LocalDate;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import lombok.Data;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Where;
+
+@Data
+@Entity
+@Table(name = "air_companies")
+@SQLDelete(sql = "UPDATE air_companies SET is_deleted = true WHERE id=?")
+@Where(clause = "is_deleted=false")
+public class AirCompany {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ @Column(nullable = false, unique = true, length = 72)
+ private String name;
+ @Column(nullable = false, length = 56)
+ private String companyType;
+ @Column(nullable = false)
+ private LocalDate foundationDate;
+ @Column(name = "is_deleted", nullable = false, columnDefinition = "boolean default false")
+ private boolean isDeleted = false;
+
+ public AirCompany() {
+ }
+
+ public AirCompany(Long id) {
+ this.id = id;
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/model/Airplane.java b/src/main/java/org/company/aircompaniesmanager/model/Airplane.java
new file mode 100644
index 0000000..e5d0d6d
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/model/Airplane.java
@@ -0,0 +1,50 @@
+package org.company.aircompaniesmanager.model;
+
+import java.time.LocalDate;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Where;
+
+@Data
+@Entity
+@Table(name = "airplanes")
+@SQLDelete(sql = "UPDATE airplanes SET is_deleted = true WHERE id=?")
+@Where(clause = "is_deleted=false")
+public class Airplane {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ @Column(nullable = false, length = 12)
+ private String factorySerialNumber;
+ @ToString.Exclude
+ @EqualsAndHashCode.Exclude
+ @JoinColumn(name = "air_company_id")
+ @ManyToOne(fetch = FetchType.LAZY)
+ private AirCompany airCompany;
+ private int numberOfFlights;
+ private double flightDistance;
+ private double fuelCapacity;
+ @Column(nullable = false, length = 56)
+ private String type;
+ private LocalDate creationDate;
+ @Column(name = "is_deleted", nullable = false, columnDefinition = "boolean default false")
+ private boolean isDeleted = false;
+
+ public Airplane() {
+ }
+
+ public Airplane(Long id) {
+ this.id = id;
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/model/Flight.java b/src/main/java/org/company/aircompaniesmanager/model/Flight.java
new file mode 100644
index 0000000..8e3df0a
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/model/Flight.java
@@ -0,0 +1,64 @@
+package org.company.aircompaniesmanager.model;
+
+import java.time.LocalDateTime;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.EnumType;
+import javax.persistence.Enumerated;
+import javax.persistence.FetchType;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.Table;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.hibernate.annotations.SQLDelete;
+import org.hibernate.annotations.Where;
+
+@Data
+@Entity
+@Table(name = "flights")
+@SQLDelete(sql = "UPDATE flights SET is_deleted = true WHERE id=?")
+@Where(clause = "is_deleted=false")
+public class Flight {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+ @Enumerated(EnumType.STRING)
+ @Column(nullable = false)
+ private Status status;
+ @ToString.Exclude
+ @EqualsAndHashCode.Exclude
+ @JoinColumn(name = "air_company_id", nullable = false)
+ @ManyToOne(fetch = FetchType.LAZY)
+ private AirCompany airCompany;
+ @ToString.Exclude
+ @EqualsAndHashCode.Exclude
+ @JoinColumn(name = "airplane_id", nullable = false)
+ @ManyToOne(fetch = FetchType.LAZY)
+ private Airplane airplane;
+ @Column(nullable = false)
+ private String departureCountry;
+ @Column(nullable = false)
+ private String destinationCountry;
+ @Column(nullable = false)
+ private double distance;
+ @Column(nullable = false)
+ private double estimatedTime;
+ private LocalDateTime startTime;
+ private LocalDateTime endTime;
+ private LocalDateTime delayStartTime;
+ private LocalDateTime creationDate;
+ @Column(name = "is_deleted", nullable = false, columnDefinition = "boolean default false")
+ private boolean isDeleted = false;
+
+ public enum Status {
+ ACTIVE,
+ COMPLETED,
+ DELAYED,
+ PENDING
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/repository/AirCompanyRepository.java b/src/main/java/org/company/aircompaniesmanager/repository/AirCompanyRepository.java
new file mode 100644
index 0000000..aa3ac05
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/repository/AirCompanyRepository.java
@@ -0,0 +1,13 @@
+package org.company.aircompaniesmanager.repository;
+
+import java.util.Optional;
+import org.company.aircompaniesmanager.model.AirCompany;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface AirCompanyRepository extends JpaRepository {
+ Optional findByName(String name);
+
+ void deleteByName(String name);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/repository/AirplaneRepository.java b/src/main/java/org/company/aircompaniesmanager/repository/AirplaneRepository.java
new file mode 100644
index 0000000..deedb95
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/repository/AirplaneRepository.java
@@ -0,0 +1,7 @@
+package org.company.aircompaniesmanager.repository;
+
+import org.company.aircompaniesmanager.model.Airplane;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface AirplaneRepository extends JpaRepository {
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/repository/FlightRepository.java b/src/main/java/org/company/aircompaniesmanager/repository/FlightRepository.java
new file mode 100644
index 0000000..2b63424
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/repository/FlightRepository.java
@@ -0,0 +1,23 @@
+package org.company.aircompaniesmanager.repository;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import org.company.aircompaniesmanager.model.Flight;
+import org.company.aircompaniesmanager.model.Flight.Status;
+import org.springframework.data.domain.Pageable;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+public interface FlightRepository extends JpaRepository {
+ List findAllByAirCompanyIdAndStatus(Long id, Status status, Pageable pageable);
+
+ @Query("SELECT f FROM Flight f WHERE (f.startTime > :localDateTime) AND (f.status = :status)")
+ List findAllExpired(LocalDateTime localDateTime, Status status, Pageable pageable);
+
+ @Query(
+ value = "SELECT * FROM `air_companies_management`.`flights` "
+ + "WHERE TIMESTAMPDIFF(minute, start_time, end_time) >= estimated_time",
+ nativeQuery = true
+ )
+ List findAllOverdue(Pageable pageable);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/service/air/company/AirCompanyService.java b/src/main/java/org/company/aircompaniesmanager/service/air/company/AirCompanyService.java
new file mode 100644
index 0000000..df95170
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/service/air/company/AirCompanyService.java
@@ -0,0 +1,21 @@
+package org.company.aircompaniesmanager.service.air.company;
+
+import java.util.List;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyRequestDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyResponseDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyUpdateRequestDto;
+import org.springframework.data.domain.Pageable;
+
+public interface AirCompanyService {
+ List findAll(Pageable pageable);
+
+ AirCompanyResponseDto findById(Long id);
+
+ AirCompanyResponseDto findByName(String name);
+
+ AirCompanyResponseDto save(AirCompanyRequestDto requestDto);
+
+ AirCompanyResponseDto updateById(Long id, AirCompanyUpdateRequestDto requestDto);
+
+ void deleteById(Long id);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/service/air/company/AirCompanyServiceImpl.java b/src/main/java/org/company/aircompaniesmanager/service/air/company/AirCompanyServiceImpl.java
new file mode 100644
index 0000000..bdff0ca
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/service/air/company/AirCompanyServiceImpl.java
@@ -0,0 +1,70 @@
+package org.company.aircompaniesmanager.service.air.company;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import javax.persistence.EntityNotFoundException;
+import lombok.RequiredArgsConstructor;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyRequestDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyResponseDto;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyUpdateRequestDto;
+import org.company.aircompaniesmanager.mapper.AirCompanyMapper;
+import org.company.aircompaniesmanager.model.AirCompany;
+import org.company.aircompaniesmanager.repository.AirCompanyRepository;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@RequiredArgsConstructor
+public class AirCompanyServiceImpl implements AirCompanyService {
+ private final AirCompanyMapper airCompanyMapper;
+ private final AirCompanyRepository airCompanyRepository;
+
+ @Override
+ public List findAll(Pageable pageable) {
+ return airCompanyRepository.findAll(pageable).stream()
+ .map(airCompanyMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public AirCompanyResponseDto findById(Long id) {
+ AirCompany airCompany = airCompanyRepository.findById(id).orElseThrow(
+ () -> new EntityNotFoundException("Can't find air company by id: " + id)
+ );
+ return airCompanyMapper.toDto(airCompany);
+ }
+
+ @Override
+ public AirCompanyResponseDto findByName(String name) {
+ AirCompany airCompany = airCompanyRepository.findByName(name).orElseThrow(
+ () -> new EntityNotFoundException("Can't find air company by name: " + name)
+ );
+ return airCompanyMapper.toDto(airCompany);
+ }
+
+ @Override
+ public AirCompanyResponseDto save(AirCompanyRequestDto requestDto) {
+ AirCompany airCompany = airCompanyRepository.save(airCompanyMapper.toEntity(requestDto));
+ return airCompanyMapper.toDto(airCompany);
+ }
+
+ @Override
+ @Transactional
+ public AirCompanyResponseDto updateById(
+ Long id,
+ AirCompanyUpdateRequestDto requestDto
+ ) {
+ AirCompany airCompany = airCompanyRepository.findById(id).orElseThrow(
+ () -> new EntityNotFoundException("Can't find air company by id: " + id)
+ );
+ airCompany.setCompanyType(requestDto.getCompanyType());
+ return airCompanyMapper.toDto(airCompanyRepository.save(airCompany));
+ }
+
+ @Override
+ @Transactional
+ public void deleteById(Long id) {
+ airCompanyRepository.deleteById(id);
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/service/airplane/AirplaneService.java b/src/main/java/org/company/aircompaniesmanager/service/airplane/AirplaneService.java
new file mode 100644
index 0000000..c8166b9
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/service/airplane/AirplaneService.java
@@ -0,0 +1,17 @@
+package org.company.aircompaniesmanager.service.airplane;
+
+import java.util.List;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneRequestDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneResponseDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneUpdateRequestDto;
+import org.springframework.data.domain.Pageable;
+
+public interface AirplaneService {
+ AirplaneResponseDto findById(Long id);
+
+ List findAll(Pageable pageable);
+
+ AirplaneResponseDto save(AirplaneRequestDto requestDto);
+
+ AirplaneResponseDto updateCompany(Long id, AirplaneUpdateRequestDto requestDto);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/service/airplane/AirplaneServiceImpl.java b/src/main/java/org/company/aircompaniesmanager/service/airplane/AirplaneServiceImpl.java
new file mode 100644
index 0000000..54aad90
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/service/airplane/AirplaneServiceImpl.java
@@ -0,0 +1,57 @@
+package org.company.aircompaniesmanager.service.airplane;
+
+import java.util.List;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneRequestDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneResponseDto;
+import org.company.aircompaniesmanager.dto.airplane.AirplaneUpdateRequestDto;
+import org.company.aircompaniesmanager.exception.EntityNotFoundException;
+import org.company.aircompaniesmanager.mapper.AirplaneMapper;
+import org.company.aircompaniesmanager.model.AirCompany;
+import org.company.aircompaniesmanager.model.Airplane;
+import org.company.aircompaniesmanager.repository.AirplaneRepository;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@RequiredArgsConstructor
+public class AirplaneServiceImpl implements AirplaneService {
+ private final AirplaneMapper airplaneMapper;
+ private final AirplaneRepository airplaneRepository;
+
+ @Override
+ public AirplaneResponseDto findById(Long id) {
+ Airplane airplane = airplaneRepository.findById(id).orElseThrow(() ->
+ new EntityNotFoundException("Can't find airplane with id: " + id)
+ );
+ return airplaneMapper.toDto(airplane);
+ }
+
+ @Override
+ public List findAll(Pageable pageable) {
+ return airplaneRepository.findAll(pageable).stream()
+ .map(airplaneMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public AirplaneResponseDto save(AirplaneRequestDto requestDto) {
+ Airplane airplane = airplaneMapper.toEntity(requestDto);
+ if (requestDto.getAirCompanyId() != null) {
+ airplane.setAirCompany(new AirCompany(requestDto.getAirCompanyId()));
+ }
+ return airplaneMapper.toDto(airplaneRepository.save(airplane));
+ }
+
+ @Override
+ @Transactional
+ public AirplaneResponseDto updateCompany(Long id, AirplaneUpdateRequestDto requestDto) {
+ Airplane airplane = airplaneRepository.findById(id).orElseThrow(() ->
+ new EntityNotFoundException("Can't find airplane with id: " + id)
+ );
+ airplane.setAirCompany(new AirCompany(id));
+ return airplaneMapper.toDto(airplaneRepository.save(airplane));
+ }
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/service/flight/FlightService.java b/src/main/java/org/company/aircompaniesmanager/service/flight/FlightService.java
new file mode 100644
index 0000000..ad455c7
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/service/flight/FlightService.java
@@ -0,0 +1,27 @@
+package org.company.aircompaniesmanager.service.flight;
+
+import java.util.List;
+import org.company.aircompaniesmanager.dto.flight.FlightRequestDto;
+import org.company.aircompaniesmanager.dto.flight.FlightResponseDto;
+import org.company.aircompaniesmanager.dto.flight.FlightUpdateRequestDto;
+import org.springframework.data.domain.Pageable;
+
+public interface FlightService {
+ List findAll(Pageable pageable);
+
+ List findAllByCompanyName(
+ String companyName,
+ String statusString,
+ Pageable pageable
+ );
+
+ List findAllExpired(Pageable pageable);
+
+ List findAllOverdue(Pageable pageable);
+
+ FlightResponseDto findById(Long id);
+
+ FlightResponseDto save(FlightRequestDto requestDto);
+
+ FlightResponseDto updateStatus(Long id, FlightUpdateRequestDto requestDto);
+}
diff --git a/src/main/java/org/company/aircompaniesmanager/service/flight/FlightServiceImpl.java b/src/main/java/org/company/aircompaniesmanager/service/flight/FlightServiceImpl.java
new file mode 100644
index 0000000..b47698a
--- /dev/null
+++ b/src/main/java/org/company/aircompaniesmanager/service/flight/FlightServiceImpl.java
@@ -0,0 +1,112 @@
+package org.company.aircompaniesmanager.service.flight;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.stream.Collectors;
+import lombok.RequiredArgsConstructor;
+import org.company.aircompaniesmanager.dto.air.company.AirCompanyResponseDto;
+import org.company.aircompaniesmanager.dto.flight.FlightRequestDto;
+import org.company.aircompaniesmanager.dto.flight.FlightResponseDto;
+import org.company.aircompaniesmanager.dto.flight.FlightUpdateRequestDto;
+import org.company.aircompaniesmanager.exception.EntityNotFoundException;
+import org.company.aircompaniesmanager.mapper.FlightMapper;
+import org.company.aircompaniesmanager.model.AirCompany;
+import org.company.aircompaniesmanager.model.Airplane;
+import org.company.aircompaniesmanager.model.Flight;
+import org.company.aircompaniesmanager.model.Flight.Status;
+import org.company.aircompaniesmanager.repository.FlightRepository;
+import org.company.aircompaniesmanager.service.air.company.AirCompanyService;
+import org.springframework.data.domain.Pageable;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+@Service
+@RequiredArgsConstructor
+public class FlightServiceImpl implements FlightService {
+ private static final int EXPIRATION_LIMIT_IN_HOURS = 24;
+
+ private final FlightMapper flightMapper;
+ private final AirCompanyService airCompanyService;
+ private final FlightRepository flightRepository;
+
+ @Override
+ public List findAll(Pageable pageable) {
+ return flightRepository.findAll(pageable).stream()
+ .map(flightMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List findAllByCompanyName(
+ String name,
+ String statusString,
+ Pageable pageable
+ ) {
+ Status status = Status.valueOf(statusString.toUpperCase());
+ AirCompanyResponseDto airCompanyResponseDto = airCompanyService.findByName(name);
+ return flightRepository
+ .findAllByAirCompanyIdAndStatus(
+ airCompanyResponseDto.getId(),
+ status,
+ pageable)
+ .stream()
+ .map(flightMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List findAllExpired(Pageable pageable) {
+ LocalDateTime expirationLimit = LocalDateTime.now().minusHours(EXPIRATION_LIMIT_IN_HOURS);
+ return flightRepository.findAllExpired(expirationLimit, Status.ACTIVE, pageable).stream()
+ .map(flightMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public List findAllOverdue(Pageable pageable) {
+ return flightRepository.findAllOverdue(pageable).stream()
+ .map(flightMapper::toDto)
+ .collect(Collectors.toList());
+ }
+
+ @Override
+ public FlightResponseDto findById(Long id) {
+ Flight flight = flightRepository.findById(id).orElseThrow(() ->
+ new EntityNotFoundException("Can't find flight with id: " + id)
+ );
+ return flightMapper.toDto(flight);
+ }
+
+ @Override
+ public FlightResponseDto save(FlightRequestDto requestDto) {
+ Flight flight = flightMapper.toEntity(requestDto);
+ flight.setAirCompany(new AirCompany(requestDto.getAirCompanyId()));
+ flight.setAirplane(new Airplane(requestDto.getAirplaneId()));
+ flight.setStatus(Status.PENDING);
+ flight.setCreationDate(LocalDateTime.now());
+ return flightMapper.toDto(flightRepository.save(flight));
+ }
+
+ @Override
+ @Transactional
+ public FlightResponseDto updateStatus(Long id, FlightUpdateRequestDto requestDto) {
+ Flight flight = flightRepository.findById(id).orElseThrow(() ->
+ new EntityNotFoundException("Can't find flight with id: " + id)
+ );
+ Status status = requestDto.getStatus();
+ flight.setStatus(status);
+ switch (status) {
+ case DELAYED:
+ flight.setDelayStartTime(LocalDateTime.now());
+ break;
+ case ACTIVE:
+ flight.setStartTime(LocalDateTime.now());
+ break;
+ case COMPLETED:
+ flight.setEndTime(LocalDateTime.now());
+ break;
+ default: break;
+ }
+ return flightMapper.toDto(flightRepository.save(flight));
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 18f22cd..bec7acd 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1 +1,15 @@
spring.application.name=air-companies-manager
+server.servlet.context-path=/api
+spring.datasource.url=jdbc:mysql://localhost:3306/air_companies_management
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+spring.datasource.username=root
+spring.datasource.password=default
+spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect
+spring.jpa.open-in-view=false
+spring.jpa.show-sql=true
+spring.jpa.generate-ddl=true
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jackson.deserialization.fail-on-unknown-properties=true
+spring.datasource.initialization-mode=always
+spring.datasource.data=classpath:data/data.sql
+springdoc.swagger-ui.path=/swagger-ui.html
diff --git a/src/main/resources/data/data.sql b/src/main/resources/data/data.sql
new file mode 100644
index 0000000..bdb0595
--- /dev/null
+++ b/src/main/resources/data/data.sql
@@ -0,0 +1,35 @@
+INSERT INTO air_companies (name, company_type, foundation_date)
+VALUES ('name', 'type', '2024-01-01'),
+ ('Delta Air Lines', 'Airlines', '1928-12-03'),
+ ('American Airlines', 'Airlines', '1926-04-15'),
+ ('Southwest Airlines', 'Airlines', '1967-03-15'),
+ ('Spirit Airlines', 'Airlines', '1983-01-01'),
+ ('SpaceX', 'Astronautics', '2002-03-14'),
+ ('Lockheed Martin', 'Aerospace', '1995-03-01'),
+ ('Northrop Grumman Corporation', 'Aerospace', '1994-01-01'),
+ ('Boeing Co', 'Airplane', '1916-07-15');
+
+INSERT INTO airplanes (
+ factory_serial_number,
+ air_company_id,
+ number_of_flights,
+ flight_distance,
+ fuel_capacity,
+ type,
+ creation_date
+) VALUES ('number', 1, 12, 3000000, 1200, 'Airbus', '2024-01-01'),
+ ('30020B', 1, 12, 2039, 1500, 'Airbus', '2024-01-01'),
+ ('27620B', 2, 49, 35735, 1800, 'Airbus', '2024-01-01'),
+ ('14920B', 3, 44, 38787, 3000, 'Airbus', '2024-01-01'),
+ ('14227B', 4, 35, 36219, 2500, 'Airbus', '2024-01-01'),
+ ('19027C', 5, 178, 452897, 3700, 'Airbus', '2024-01-01'),
+ ('90047E', 6, 16, 1783, 4500, 'Airbus', '2024-01-01'),
+ ('20954K', 7, 866, 900000, 5000, 'Airbus', '2024-01-01'),
+ ('27891B', 8, 136, 519697, 3444, 'Airbus', '2024-01-01'),
+ ('21987J', 9, 246, 37487, 1200, 'Airbus', '2024-01-01'),
+ ('91331L', 5, 468, 800653, 1200, 'Airbus', '2024-01-01'),
+ ('17979P', 5, 222, 652333, 1200, 'Airbus', '2024-01-01'),
+ ('18994O', 6, 290, 756678, 1200, 'Airbus', '2024-01-01'),
+ ('17987I', 6, 134, 123345, 1200, 'Airbus', '2024-01-01'),
+ ('79849S', 7, 65, 75632, 1200, 'Airbus', '2024-01-01'),
+ ('19894R', 7, 211, 253000, 1200, 'Airbus', '2024-01-01');
diff --git a/src/test/java/org/company/aircompaniesmanager/AirCompaniesManagerApplicationTests.java b/src/test/java/org/company/aircompaniesmanager/AirCompaniesManagerApplicationTests.java
index c9be274..1235fcd 100644
--- a/src/test/java/org/company/aircompaniesmanager/AirCompaniesManagerApplicationTests.java
+++ b/src/test/java/org/company/aircompaniesmanager/AirCompaniesManagerApplicationTests.java
@@ -1,13 +1,7 @@
package org.company.aircompaniesmanager;
-import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AirCompaniesManagerApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
}