Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Job Posting Functionality Implementation #50

Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2b01b33
feat: Implement Job model for job postings
AhmedFatthy1040 Oct 28, 2024
4978530
feat: Define JobStatus enum for job posting lifecycle
AhmedFatthy1040 Oct 28, 2024
941ccbf
feat: Define JobType enum for job posting types
AhmedFatthy1040 Oct 28, 2024
e3afcc3
Refactored Job entity variable names for improved readability.
AhmedFatthy1040 Oct 28, 2024
864a2f7
Created JobRepository to interact with the 'jobs' table in the database.
AhmedFatthy1040 Oct 28, 2024
552df0a
feat: Create JobDTO class for job data transfer
AhmedFatthy1040 Oct 28, 2024
11a43e9
feat: Define JobService interface for job management
AhmedFatthy1040 Oct 28, 2024
42b3f4b
feat: Implement JobMapper for Job and JobDTO conversion
AhmedFatthy1040 Oct 28, 2024
2f7aa7f
feat: Implement getCurrentUserId method for authentication
AhmedFatthy1040 Oct 28, 2024
5b88751
feat: Implement job creation in JobServiceImpl
AhmedFatthy1040 Oct 28, 2024
ddb3a87
feat: Implement JobController for managing job-related operations
AhmedFatthy1040 Oct 28, 2024
1b50c12
fix: Rename 'id' to 'jobId' in JobDTO class
AhmedFatthy1040 Oct 28, 2024
796b94c
fix: Update field names in JobMapper for consistency
AhmedFatthy1040 Oct 28, 2024
9ca2e41
Refactor JobStatus enum: Change enum constants to capitalize only the…
AhmedFatthy1040 Oct 28, 2024
e9d3057
Refactor JobType enum: Change enum constants to capitalize only the f…
AhmedFatthy1040 Oct 28, 2024
7b1f46a
Enhance JobServiceImpl: Add exception handling for user authenticatio…
AhmedFatthy1040 Oct 28, 2024
9c51b8c
Add unit tests for JobServiceImpl
AhmedFatthy1040 Oct 28, 2024
76cb950
Fix: Handle missing roles and users in assignRolesToUser
AhmedFatthy1040 Oct 28, 2024
09dcf63
Refactor unit test for role assignment to match updated method signature
AhmedFatthy1040 Oct 28, 2024
0d9446a
Merge remote-tracking branch 'upstream/main' into issue-37-posting-jo…
AhmedFatthy1040 Nov 2, 2024
4d6a145
Remove 'status' field from JobDTO as it's now set to 'Open' by default.
AhmedFatthy1040 Nov 2, 2024
016c667
Set default 'status' to 'Open' in JobMapper.
AhmedFatthy1040 Nov 2, 2024
cb9427e
fix: Renamed migration file V5_Create_user_profile_to_all_inserted_us…
AhmedFatthy1040 Nov 2, 2024
18418a4
Updated the JobServiceImplTest based on the new changes in JobDTO tha…
AhmedFatthy1040 Nov 2, 2024
0dff100
Fix Checkstyle violations in JobController
AhmedFatthy1040 Nov 2, 2024
509e0af
feat: add Skill entity and configure relationships with Job and UserP…
AhmedFatthy1040 Nov 23, 2024
dceed54
Commit Message:
AhmedFatthy1040 Nov 23, 2024
baf771a
chore: add Flyway migration script to insert test skills
AhmedFatthy1040 Nov 23, 2024
a481a35
test: update JobServiceImplTest to support skill association
AhmedFatthy1040 Nov 23, 2024
0b6ea96
fix: correct indentation for error handling in JobServiceImpl
AhmedFatthy1040 Nov 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.activecourses.upwork.controller.job;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import com.activecourses.upwork.dto.JobDTO;
import com.activecourses.upwork.dto.ResponseDto;
import com.activecourses.upwork.mapper.JobMapper;
import com.activecourses.upwork.model.Job;
import com.activecourses.upwork.service.job.JobService;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;

@Tag(name = "Job", description = "Job Management API")
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/jobs/")
public class JobController {
private final JobService jobService;
private final JobMapper jobMapper;

@Operation(
summary = "Create a new job",
description = "Creates a new job posting",
security = @SecurityRequirement(name = "bearerAuth")
)
@PreAuthorize("hasRole('ADMIN') or hasRole('CLIENT') or hasRole('FREELANCER')")
@PostMapping("/post")
public ResponseEntity<ResponseDto> createJob(@RequestBody JobDTO jobDTO) {
Job createdJob = jobService.createJob(jobDTO);
return buildResponseEntity(HttpStatus.CREATED, true, jobMapper.mapTo(createdJob), null);
}

private ResponseEntity<ResponseDto> buildResponseEntity(HttpStatus status, boolean success, Object data, Object error) {
return ResponseEntity
.status(status)
.body(ResponseDto
.builder()
.status(status)
.success(success)
.data(data)
.error(error)
.build()
);
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/activecourses/upwork/dto/JobDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.activecourses.upwork.dto;

import java.math.BigDecimal;
import java.time.LocalDateTime;

import com.activecourses.upwork.model.JobStatus;
import com.activecourses.upwork.model.JobType;

import lombok.Data;

@Data
public class JobDTO {
private Integer jobId;
private String title;
private String description;
private BigDecimal budget;
private JobType jobType;
private JobStatus status;
private LocalDateTime createdAt;
}
36 changes: 36 additions & 0 deletions src/main/java/com/activecourses/upwork/mapper/JobMapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.activecourses.upwork.mapper;

import org.springframework.stereotype.Component;

import com.activecourses.upwork.dto.JobDTO;
import com.activecourses.upwork.model.Job;

@Component
public class JobMapper implements Mapper<Job, JobDTO> {

@Override
public JobDTO mapTo(Job job) {
JobDTO jobDTO = new JobDTO();
jobDTO.setJobId(job.getJobId());
jobDTO.setTitle(job.getTitle());
jobDTO.setDescription(job.getDescription());
jobDTO.setBudget(job.getBudget());
jobDTO.setJobType(job.getJobType());
jobDTO.setStatus(job.getStatus());
jobDTO.setCreatedAt(job.getCreatedAt());
return jobDTO;
}

@Override
public Job mapFrom(JobDTO jobDTO) {
Job job = new Job();
job.setJobId(jobDTO.getJobId());
job.setTitle(jobDTO.getTitle());
job.setDescription(jobDTO.getDescription());
job.setBudget(jobDTO.getBudget());
job.setJobType(jobDTO.getJobType());
job.setStatus(jobDTO.getStatus());
job.setCreatedAt(jobDTO.getCreatedAt());
return job;
}
}
50 changes: 50 additions & 0 deletions src/main/java/com/activecourses/upwork/model/Job.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package com.activecourses.upwork.model;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import jakarta.persistence.*;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity
@Table(name = "jobs")
public class Job {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer jobId;

@ManyToOne
@JoinColumn(name = "client_id")
private User client;

@Column(nullable = false, length = 255)
private String title;

@Column(nullable = false, columnDefinition = "TEXT")
private String description;

@Column(nullable = false)
private BigDecimal budget;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private JobType jobType;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private JobStatus status;

@Builder.Default
@Column(nullable = false, updatable = false)
private LocalDateTime createdAt = LocalDateTime.now();
}
8 changes: 8 additions & 0 deletions src/main/java/com/activecourses/upwork/model/JobStatus.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.activecourses.upwork.model;

public enum JobStatus {
Open,
Closed,
InProgress;

}
7 changes: 7 additions & 0 deletions src/main/java/com/activecourses/upwork/model/JobType.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.activecourses.upwork.model;

public enum JobType {
Hourly,
Fixed;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.activecourses.upwork.repository.job;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.activecourses.upwork.model.Job;

@Repository
public interface JobRepository extends JpaRepository<Job, Integer> {

}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ public interface AuthService {
boolean deactivateUser(int userId);

boolean reactivateUser(int userId);

Integer getCurrentUserId();
}
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,17 @@ public boolean reactivateUser(int userId) {
return true;
}

@Override
public Integer getCurrentUserId() {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (authentication != null && authentication.isAuthenticated()) {
UserDetails userDetails = (UserDetails) authentication.getPrincipal();
User user = (User) userDetails;
return user.getId();
}
return null;
}

static User unwrapUser(Optional<User> entity) {
if (entity.isPresent()) return entity.get();
else throw new UnsupportedOperationException("Unimplemented method 'unwrapUser'");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.activecourses.upwork.service.job;

import com.activecourses.upwork.dto.JobDTO;
import com.activecourses.upwork.model.Job;

public interface JobService {
Job createJob(JobDTO jobDTO);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.activecourses.upwork.service.job;

import org.springframework.stereotype.Service;

import com.activecourses.upwork.dto.JobDTO;
import com.activecourses.upwork.mapper.JobMapper;
import com.activecourses.upwork.model.Job;
import com.activecourses.upwork.model.User;
import com.activecourses.upwork.repository.job.JobRepository;
import com.activecourses.upwork.repository.user.UserRepository;
import com.activecourses.upwork.service.authentication.AuthService;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class JobServiceImpl implements JobService {

private final JobRepository jobRepository;
private final UserRepository userRepository;
private final AuthService authService;
private final JobMapper jobMapper;

@Override
public Job createJob(JobDTO jobDTO) {
Integer clientId = authService.getCurrentUserId();
if (clientId == null) {
throw new IllegalStateException("User is not authenticated");
}

User client = userRepository.findById(clientId)
.orElseThrow(() -> new IllegalArgumentException("User not found with ID: " + clientId));

Job job = jobMapper.mapFrom(jobDTO);
job.setClient(client);

return jobRepository.save(job);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,17 @@ public boolean assignRolesToUser(int userId, Map<String, Object> roles) {
logger.info("Assigning roles to user with id: {}", userId);
Optional<User> user = userRepository.findById(userId);
User unwrappedUser = user.orElseThrow(() -> new RuntimeException("User not found: " + userId));
List<Role> roleList = roles.keySet().stream()

// Extract role names from the request body
List<String> roleNames = (List<String>) roles.get("roles");

// Fetch roles from the database
List<Role> roleList = roleNames.stream()
.map(roleName -> roleRepository.findByName(roleName)
.orElseThrow(() -> new RuntimeException("Role not found: " + roleName)))
.collect(Collectors.toList());

// Assign roles to the user
unwrappedUser.setRoles(roleList);
userRepository.save(unwrappedUser);
return true;
Expand Down
Loading