Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java	(revision 19398adb44637736271a04ab58b1f528cc33908f)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/config/SecurityConfiguration.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -30,5 +30,7 @@
         http.csrf(AbstractHttpConfigurer::disable)
                 .authorizeHttpRequests(request -> request
-                        .requestMatchers("/api/job-advertisements/all","/api/job-advertisements/view/**","/api/recruiter/info/**", "/api/auth/**").permitAll()
+                        // TO DO: FIX PERMISSIONS
+                        .requestMatchers("/api/job-advertisements/**","/api/job-advertisements/view/**","/api/recruiter/info/**",
+                                "/api/job-advertisements/apply/**","/api/auth/**", "/api/resume/**", "/api/my-applications/**", "/api/applications/{id}/update").permitAll()
                         //.requestMatchers("/api/job-advertisements/**").hasAnyAuthority(Role.ROLE_RECRUITER.name())
                         .anyRequest().authenticated())
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/ApplicationController.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/ApplicationController.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/ApplicationController.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,68 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.controllers;
+
+import lombok.AllArgsConstructor;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.Application;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationStatusDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.ApplicationService;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+import org.springframework.core.io.Resource;
+import org.springframework.http.HttpHeaders;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/api")
+@AllArgsConstructor
+@CrossOrigin(origins = "*")
+public class ApplicationController {
+    private final ApplicationService applicationService;
+
+    @GetMapping("/my-applications/{id}")
+    public ResponseEntity<?> findAllApplicationsByJobSeekerId(@PathVariable Long id) {
+        List<ApplicationDetailsDTO> applicationList = applicationService.findAllByJobSeekerId(id);
+        return new ResponseEntity<>(applicationList, HttpStatus.OK);
+    }
+
+    @GetMapping("/job-advertisements/{advertisement_id}/applications")
+    public ResponseEntity<?> findAllApplicationsByJobAdvertisementId(@PathVariable("advertisement_id") Long advertisementId) {
+        List<ApplicationDetailsDTO> applicationList = applicationService.findAllByJobAdvertisementId(advertisementId);
+        return new ResponseEntity<>(applicationList, HttpStatus.OK);
+    }
+
+    @PostMapping("/applications/{id}/update")
+    public ResponseEntity<?> updateApplicationStatus(@PathVariable("id") Long applicaitonId, @RequestBody ApplicationStatusDTO appStatusDTO) {
+        ApplicationStatusDTO applicationStatusDTO = applicationService.updateApplicationStatus(applicaitonId,appStatusDTO.getStatus());
+        return new ResponseEntity<>(applicationStatusDTO, HttpStatus.OK);
+    }
+
+    @GetMapping("/resume/{fileName:.+}")
+    public ResponseEntity<Resource> downloadResume(@PathVariable("fileName") String fileName) {
+        Resource resource = applicationService.loadResumeAsResource(fileName);
+        return ResponseEntity.ok()
+                .contentType(MediaType.APPLICATION_PDF)
+                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + resource.getFilename() + "\"")
+                .body(resource);
+    }
+
+    @PostMapping("/job-advertisements/apply")
+    public ResponseEntity<ApplicationDetailsDTO> submitApplication(
+            @RequestParam("jobSeekerId") Long jobSeekerId,
+            @RequestParam("jobAdId") Long jobAdId,
+            @RequestParam("resumeFile") MultipartFile resumeFile,
+            @RequestParam("answerOne") String answerOne,
+            @RequestParam("answerTwo") String answerTwo,
+            @RequestParam("answerThree") String answerThree,
+            @RequestParam("messageToRecruiter") String messageToRecruiter) {
+
+        ApplicationDTO applicationDTO = new ApplicationDTO(jobSeekerId, jobAdId, resumeFile, answerOne, answerTwo, answerThree, messageToRecruiter);
+        ApplicationDetailsDTO applicationDetailsDTO = applicationService.submitApplication(applicationDTO);
+        return new ResponseEntity<>(applicationDetailsDTO, HttpStatus.OK);
+    }
+
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/JobAdvertisementController.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/JobAdvertisementController.java	(revision 19398adb44637736271a04ab58b1f528cc33908f)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/controllers/JobAdvertisementController.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -3,11 +3,16 @@
 
 import lombok.AllArgsConstructor;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.Application;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdFilterDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdvertisementDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdDetailsDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.JobAdvertisement;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.ApplicationService;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.JobAdvertisementService;
 import org.springframework.http.HttpStatus;
 import org.springframework.http.ResponseEntity;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.util.List;
@@ -20,4 +25,5 @@
 
     private final JobAdvertisementService jobAdvertisementService;
+    private final ApplicationService applicationService;
 
     @PostMapping("/add")
@@ -45,4 +51,10 @@
     }
 
+    @PostMapping("/recruiter/{id}/filtered")
+    public ResponseEntity<?> filterJobAdvertisementsByRecruiterId(@PathVariable Long id, @RequestBody JobAdFilterDTO jobAdFilterDTO) {
+        List<JobAdDetailsDTO> jobAdDetailsDTOS = jobAdvertisementService.filterJobAdvertisementsByRecruiterId(id, jobAdFilterDTO);
+        return new ResponseEntity<>(jobAdDetailsDTOS, HttpStatus.OK);
+    }
+
     @GetMapping("/all")
     public ResponseEntity<?> findAllJobAdvertisements() {
@@ -51,8 +63,17 @@
     }
 
-    @GetMapping("/view/{id}")
+    @PostMapping("/filtered")
+    public ResponseEntity<?> filterJobAdvertisements(@RequestBody JobAdFilterDTO jobAdFilterDTO) {
+        List<JobAdDetailsDTO> jobAdDetailsDTOS = jobAdvertisementService.filterJobAdvertisements(jobAdFilterDTO);
+        return new ResponseEntity<>(jobAdDetailsDTOS, HttpStatus.OK);
+    }
+
+    @GetMapping("/{id}")
     public ResponseEntity<?> findJobAdvertisementById(@PathVariable Long id) {
         JobAdDetailsDTO jobAdDetailsDTO = jobAdvertisementService.findJobAdvertisementById(id);
         return new ResponseEntity<>(jobAdDetailsDTO, HttpStatus.OK);
     }
+
+
+
 }
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/Application.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/Application.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/Application.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,76 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications;
+
+import jakarta.persistence.*;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations.ApplicationStatus;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.JobAdvertisement;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.JobSeeker;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;
+
+import java.time.LocalDateTime;
+import java.util.HashMap;
+import java.util.List;
+
+@Entity
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+@Table(name = "applications")
+public class Application {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private Long id;
+
+    @ManyToOne
+    private JobSeeker jobSeeker;
+
+    @ManyToOne
+    private JobAdvertisement jobAdvertisement;
+
+    @Column(name = "resume_file_name", nullable = false)
+    private String resumeFileName;
+
+    @ElementCollection
+    private List<String> questionAnswers;
+
+    private String message;
+
+    private LocalDateTime submittedOn;
+
+    @Enumerated(EnumType.STRING)
+    private ApplicationStatus status;
+
+    public Application(JobSeeker jobSeeker, JobAdvertisement jobAdvertisement, String resumeFileName, List<String> answers, String message) {
+        this.jobSeeker = jobSeeker;
+        this.jobAdvertisement = jobAdvertisement;
+        this.resumeFileName = resumeFileName;
+        this.questionAnswers = answers;
+        this.message = message;
+        submittedOn = LocalDateTime.now();
+        this.status = ApplicationStatus.PROPOSED;
+    }
+
+    public static ApplicationDetailsDTO mapToApplicationDetailsDTO (Application application) {
+        return new ApplicationDetailsDTO(
+                application.getId(),
+                application.getJobSeeker().getId(),
+                application.getJobSeeker().getName(),
+                application.getJobSeeker().getEmail(),
+                application.getJobSeeker().getPhoneNumber(),
+                application.getJobAdvertisement().getRecruiter().getName(),
+                application.getJobAdvertisement().getRecruiter().getEmail(),
+                application.getJobAdvertisement().getRecruiter().getPhoneNumber(),
+                application.getJobAdvertisement().getId(),
+                application.getJobAdvertisement().getTitle(),
+                application.getQuestionAnswers(),
+                application.getResumeFileName(),
+                application.getMessage(),
+                application.getSubmittedOn(),
+                application.getStatus().name()
+        );
+    }
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDTO.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,17 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.springframework.web.multipart.MultipartFile;
+
+@Data
+@AllArgsConstructor
+public class ApplicationDTO {
+    private Long jobSeekerId;
+    private Long jobAdId;
+    private MultipartFile resumeFile;
+    private String answerOne;
+    private String answerTwo;
+    private String answerThree;
+    private String messageToRecruiter;
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDetailsDTO.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDetailsDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationDetailsDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,30 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO;
+
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations.ApplicationStatus;
+
+import java.time.LocalDateTime;
+import java.util.List;
+
+@Data
+@AllArgsConstructor
+public class ApplicationDetailsDTO {
+    private Long id;
+    private Long jobSeekerId;
+    private String jobSeekerName;
+    private String jobSeekerEmail;
+    private String jobSeekerPhoneNumber;
+    private String recruiterName;
+    private String recruiterEmail;
+    private String recruiterPhoneNumber;
+    private Long jobAdId;
+    private String jobAdTitle;
+    private List<String> questionAnswers;
+    private String fileName;
+    private String message;
+    private LocalDateTime submittedOn;
+    private String status;
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationStatusDTO.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationStatusDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/applications/DTO/ApplicationStatusDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,11 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class ApplicationStatusDTO {
+    Long id;
+    String status;
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/enumerations/ApplicationStatus.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/enumerations/ApplicationStatus.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/enumerations/ApplicationStatus.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,5 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations;
+
+public enum ApplicationStatus {
+    PROPOSED, UNDER_REVIEW, ACCEPTED, DENIED
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/job_advertisements/DTO/JobAdFilterDTO.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/job_advertisements/DTO/JobAdFilterDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/job_advertisements/DTO/JobAdFilterDTO.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,12 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+@Data
+@AllArgsConstructor
+public class JobAdFilterDTO {
+    String searchTerm;
+    String industry;
+    String sortOrder;
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/job_advertisements/JobAdvertisement.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/job_advertisements/JobAdvertisement.java	(revision 19398adb44637736271a04ab58b1f528cc33908f)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/models/job_advertisements/JobAdvertisement.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -8,4 +8,5 @@
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations.JobType;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.Recruiter;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;
 
@@ -20,5 +21,5 @@
 public class JobAdvertisement {
 
-    public JobAdvertisement(User recruiter, String title, String description, String industry, int startingSalary, LocalDate activeUntil, JobType jobType, EmploymentStatus employmentStatus) {
+    public JobAdvertisement(Recruiter recruiter, String title, String description, String industry, int startingSalary, LocalDate activeUntil, JobType jobType, EmploymentStatus employmentStatus) {
         this.recruiter = recruiter;
         this.title = title;
@@ -38,5 +39,5 @@
 
     @ManyToOne
-    private User recruiter;
+    private Recruiter recruiter;
 
     private String title;
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/ApplicationRepository.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/ApplicationRepository.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/ApplicationRepository.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,11 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories;
+
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.Application;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+public interface ApplicationRepository extends JpaRepository<Application, Long> {
+    List<Application> findAllByJobAdvertisementId(Long jobId);
+    List<Application> findAllByJobSeekerId(Long jobId);
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/RecruiterRepository.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/RecruiterRepository.java	(revision 19398adb44637736271a04ab58b1f528cc33908f)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/repositories/RecruiterRepository.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -5,5 +5,7 @@
 import org.springframework.data.jpa.repository.JpaRepository;
 
+import java.util.Optional;
+
 public interface RecruiterRepository extends JpaRepository<Recruiter, Long> {
-    Recruiter findRecruiterByEmail(String email);
+    Optional<Recruiter> findRecruiterByEmail(String email);
 }
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/ApplicationServiceImpl.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/ApplicationServiceImpl.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/ApplicationServiceImpl.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,119 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.impl;
+
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationStatusDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations.ApplicationStatus;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.JobSeeker;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.JobSeekerRepository;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.UrlResource;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.Application;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.JobAdvertisement;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.ApplicationRepository;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.JobAdvertisementRepository;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.UserRepository;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.ApplicationService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+//@RequiredArgsConstructor
+public class ApplicationServiceImpl implements ApplicationService {
+    private final Path fileStorageLocation;
+
+    private final UserRepository userRepository;
+    private final ApplicationRepository applicationRepository;
+    private final JobAdvertisementRepository jobAdvertisementRepository;
+    private final JobSeekerRepository jobSeekerRepository;
+
+    @Autowired
+    public ApplicationServiceImpl(@Value("${file.upload-dir}") String uploadDir, UserRepository userRepository, ApplicationRepository applicationRepository, JobAdvertisementRepository jobAdvertisementRepository,
+                                  JobSeekerRepository jobSeekerRepository) {
+        this.fileStorageLocation = Paths.get(uploadDir).toAbsolutePath().normalize();
+
+        try {
+            Files.createDirectories(this.fileStorageLocation);
+        } catch (IOException ex) {
+            throw new RuntimeException("Could not create the directory where the uploaded files will be stored.", ex);
+        }
+
+        this.userRepository = userRepository;
+        this.applicationRepository = applicationRepository;
+        this.jobAdvertisementRepository = jobAdvertisementRepository;
+        this.jobSeekerRepository = jobSeekerRepository;
+    }
+
+    @Override
+    public ApplicationDetailsDTO submitApplication(ApplicationDTO applicationDTO) {
+
+        if (applicationDTO.getResumeFile().isEmpty()) {
+            throw new RuntimeException("Failed to store empty file.");
+        }
+
+        Path targetLocation = this.fileStorageLocation.resolve(applicationDTO.getResumeFile().getOriginalFilename());
+        try {
+            Files.copy(applicationDTO.getResumeFile().getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+
+        JobSeeker jobSeeker = jobSeekerRepository.findById(applicationDTO.getJobSeekerId()).orElseThrow(() -> new IllegalArgumentException("User not found"));
+        JobAdvertisement jobAdvertisement = jobAdvertisementRepository.findById(applicationDTO.getJobAdId()).orElseThrow(() -> new IllegalArgumentException("Job Ad not found"));
+
+        List<String> answers = new ArrayList<>();
+        answers.add(applicationDTO.getAnswerOne());
+        answers.add(applicationDTO.getAnswerTwo());
+        answers.add(applicationDTO.getAnswerThree());
+
+        Application application = new Application(jobSeeker, jobAdvertisement, applicationDTO.getResumeFile().getOriginalFilename(), answers, applicationDTO.getMessageToRecruiter());
+        applicationRepository.save(application);
+        return Application.mapToApplicationDetailsDTO(application);
+    }
+
+    @Override
+    public List<ApplicationDetailsDTO> findAllByJobAdvertisementId(Long jobId) {
+        List<Application> applications =  applicationRepository.findAllByJobAdvertisementId(jobId);
+        return applications.stream().map(Application::mapToApplicationDetailsDTO).toList();
+    }
+
+    @Override
+    public List<ApplicationDetailsDTO> findAllByJobSeekerId(Long jobSeekerId) {
+       List<Application> applications = applicationRepository.findAllByJobSeekerId(jobSeekerId);
+       return applications.stream().map(Application::mapToApplicationDetailsDTO).toList();
+    }
+
+    @Override
+    public Resource loadResumeAsResource(String fileName) {
+        try {
+            Path filePath = fileStorageLocation.resolve(fileName).normalize();
+            Resource resource = new UrlResource(filePath.toUri());
+            if (resource.exists()) {
+                return resource;
+            } else {
+                throw new RuntimeException("File not found " + fileName);
+            }
+        } catch (IOException ex) {
+            throw new RuntimeException("File not found " + fileName, ex);
+        }
+    }
+
+    @Override
+    public ApplicationStatusDTO updateApplicationStatus(Long id, String status) {
+       Application application = applicationRepository.findById(id).orElse(null);
+        System.out.println(status);
+       application.setStatus(ApplicationStatus.valueOf(status));
+       applicationRepository.save(application);
+       return new ApplicationStatusDTO(id, status);
+    }
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/JobAdvertisementServiceImpl.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/JobAdvertisementServiceImpl.java	(revision 19398adb44637736271a04ab58b1f528cc33908f)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/impl/JobAdvertisementServiceImpl.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -5,8 +5,11 @@
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.enumerations.JobType;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdFilterDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdvertisementDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.JobAdvertisement;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.Recruiter;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.users.User;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.JobAdvertisementRepository;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.RecruiterRepository;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.repositories.UserRepository;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef.JobAdvertisementService;
@@ -15,4 +18,5 @@
 import java.time.LocalDate;
 import java.time.LocalDateTime;
+import java.util.Comparator;
 import java.util.List;
 
@@ -22,8 +26,9 @@
     private final UserRepository userRepository;
     private final JobAdvertisementRepository jobAdvertisementRepository;
+    private final RecruiterRepository recruiterRepository;
 
     @Override
     public JobAdDetailsDTO addJobAdvertisement(JobAdvertisementDTO jobAdvertisementDTO) {
-        User recruiter = userRepository.findByEmail(jobAdvertisementDTO.getEmail()).orElseThrow(() -> new IllegalArgumentException("User not found"));
+        Recruiter recruiter = recruiterRepository.findRecruiterByEmail(jobAdvertisementDTO.getEmail()).orElseThrow(() -> new IllegalArgumentException("User not found"));
         JobAdvertisement jobAdvertisement = new JobAdvertisement(
                 recruiter,
@@ -35,5 +40,5 @@
                 JobType.valueOf(jobAdvertisementDTO.getJobType()),
                 EmploymentStatus.valueOf(jobAdvertisementDTO.getEmploymentStatus())
-                );
+        );
         jobAdvertisementRepository.save(jobAdvertisement);
         return JobAdvertisement.mapToJobAdDetailsDTO(jobAdvertisement);
@@ -79,15 +84,35 @@
 
     @Override
+    public List<JobAdDetailsDTO> filterJobAdvertisements(JobAdFilterDTO jobAdFilterDTO) {
+        List<JobAdvertisement> filteredJobAds = jobAdvertisementRepository.findAll();
+        filteredJobAds = filter(filteredJobAds, jobAdFilterDTO);
+
+        return filteredJobAds.stream()
+                .map(JobAdvertisement::mapToJobAdDetailsDTO)
+                .toList();
+    }
+
+    private List<JobAdvertisement> filter(List<JobAdvertisement> filteredJobAdvertisements, JobAdFilterDTO jobAdFilterDTO) {
+        return filteredJobAdvertisements.stream()
+                .filter(jobAd -> jobAd.getTitle().toLowerCase().contains(jobAdFilterDTO.getSearchTerm().toLowerCase()))
+                .filter(jobAd -> jobAdFilterDTO.getIndustry().equals("all") || jobAd.getIndustry().equals(jobAdFilterDTO.getIndustry()))
+                .sorted(getComparator(jobAdFilterDTO.getSortOrder()))
+                .toList();
+    }
+
+    private Comparator<JobAdvertisement> getComparator(String sortOrder) {
+        return switch (sortOrder) {
+            case "date_newest" -> Comparator.comparing(JobAdvertisement::getPostedOn).reversed();
+            case "date_oldest" -> Comparator.comparing(JobAdvertisement::getPostedOn);
+            case "salary_highest" -> Comparator.comparing(JobAdvertisement::getStartingSalary).reversed();
+            case "salary_lowest" -> Comparator.comparing(JobAdvertisement::getStartingSalary);
+            default -> Comparator.comparing(JobAdvertisement::getPostedOn); // Default sorting order
+        };
+    }
+
+
+    @Override
     public List<JobAdDetailsDTO> findAllJobAdvertisementsByRecruiterId(Long recruiterId) {
         List<JobAdvertisement> jobAdvertisementList = jobAdvertisementRepository.findAllByRecruiterId(recruiterId);
-//        jobAdvertisementList.forEach(jobAdvertisement -> {
-//            if (!jobAdvertisement.isJobAdActive() && jobAdvertisement.isActive()) {
-//                jobAdvertisement.setActive(false);
-//                jobAdvertisementRepository.save(jobAdvertisement);
-//            } else if (jobAdvertisement.isJobAdActive() && !jobAdvertisement.isActive()) {
-//                jobAdvertisement.setActive(true);
-//                jobAdvertisementRepository.save(jobAdvertisement);
-//            }
-//        });
 
         return jobAdvertisementList.stream()
@@ -95,4 +120,14 @@
                 .toList();
     }
+
+    @Override
+    public List<JobAdDetailsDTO> filterJobAdvertisementsByRecruiterId(Long recruiterId, JobAdFilterDTO jobAdFilterDTO) {
+        List<JobAdvertisement> filteredJobAds = jobAdvertisementRepository.findAllByRecruiterId(recruiterId);
+        filteredJobAds = filter(filteredJobAds, jobAdFilterDTO);
+        return filteredJobAds.stream()
+                .map(JobAdvertisement::mapToJobAdDetailsDTO)
+                .toList();
+    }
+
     @Override
     public JobAdDetailsDTO findJobAdvertisementById(Long id) {
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/ApplicationService.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/ApplicationService.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/ApplicationService.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -0,0 +1,18 @@
+package mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.service.intef;
+
+
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.Application;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.applications.DTO.ApplicationStatusDTO;
+import org.springframework.core.io.Resource;
+
+import java.util.List;
+
+public interface ApplicationService {
+    ApplicationDetailsDTO submitApplication(ApplicationDTO applicationDTO);
+    List<ApplicationDetailsDTO> findAllByJobAdvertisementId(Long jobId);
+    List<ApplicationDetailsDTO> findAllByJobSeekerId(Long jobSeekerId);
+    Resource loadResumeAsResource(String fileName);
+    ApplicationStatusDTO updateApplicationStatus(Long id, String status);
+}
Index: jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/JobAdvertisementService.java
===================================================================
--- jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/JobAdvertisementService.java	(revision 19398adb44637736271a04ab58b1f528cc33908f)
+++ jobvista-backend/src/main/java/mk/ukim/finki/predmeti/internettehnologii/jobvistabackend/service/intef/JobAdvertisementService.java	(revision 28b3398dcd7f9cfd044c2cb7923434b06037fee2)
@@ -2,4 +2,5 @@
 
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdDetailsDTO;
+import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdFilterDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.DTO.JobAdvertisementDTO;
 import mk.ukim.finki.predmeti.internettehnologii.jobvistabackend.models.job_advertisements.JobAdvertisement;
@@ -14,5 +15,7 @@
 
     List<JobAdDetailsDTO> findAllJobAdvertisements();
+    List<JobAdDetailsDTO> filterJobAdvertisements(JobAdFilterDTO jobAdFilterDTO);
     List<JobAdDetailsDTO> findAllJobAdvertisementsByRecruiterId(Long recruiterId);
+    List<JobAdDetailsDTO> filterJobAdvertisementsByRecruiterId(Long recruiterId, JobAdFilterDTO jobAdFilterDTO);
     JobAdDetailsDTO findJobAdvertisementById(Long id);
 
