Skip to content

Commit 495e90a

Browse files
authored
Merge pull request #80 from techstartucalgary/suhaib/job_routers
Suhaib/job routers
2 parents a274681 + 8ce6a09 commit 495e90a

File tree

5 files changed

+102
-16
lines changed

5 files changed

+102
-16
lines changed

backend/crud/user_profile_job_crud.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,35 @@ def delete_applicant_application(db: Session, user_id: int, job_id: int) \
194194
db.delete(application)
195195
db.commit()
196196
return application
197+
198+
def update_applicant_application_status(db: Session,
199+
user_id: int,
200+
job_id: int,
201+
new_status: application_status_model.ApplicationStatusEnum,
202+
rejection_feedback: str | None) \
203+
-> user_profile_job_model.UserProfileJob:
204+
# Get the application
205+
current_application = get_application_by_user_id_and_job_id(db, user_id, job_id)
206+
207+
# Get the id for the new application status
208+
new_application_status_id = application_status_crud.get_application_status_by_name(db, new_status.value).id
209+
210+
# Update the current applications id
211+
current_application.application_status_id = new_application_status_id
212+
213+
# Update the other attributes of the current application depending on the new status
214+
if new_status.value == application_status_model.ApplicationStatusEnum.submitted.value:
215+
current_application.application_submitted_date = datetime.today()
216+
elif new_status.value == application_status_model.ApplicationStatusEnum.in_review.value:
217+
current_application.application_reviewed_date = datetime.today()
218+
elif new_status.value == application_status_model.ApplicationStatusEnum.screening.value:
219+
current_application.application_further_screening_date = datetime.today()
220+
elif new_status.value == application_status_model.ApplicationStatusEnum.rejected.value:
221+
current_application.application_rejected_date = datetime.today()
222+
current_application.rejection_feedback = rejection_feedback
223+
elif new_status.value == application_status_model.ApplicationStatusEnum.offer_sent.value:
224+
current_application.application_offer_sent_date = datetime.today()
225+
226+
db.commit()
227+
db.refresh(current_application)
228+
return current_application

backend/models/user_profile_job_model.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class UserProfileJob(Base):
1515
application_status_id = Column(Integer, ForeignKey("application_status.id"), nullable=False)
1616
application_submitted_date = Column(Date, nullable=False)
1717
application_reviewed_date = Column(Date, nullable=True)
18+
application_further_screening_date = Column(Date, nullable=True)
1819
application_offer_sent_date = Column(Date, nullable=True)
1920
application_rejected_date = Column(Date, nullable=True)
2021
rejection_feedback = Column(String, nullable=True)

backend/routers/user_profile_job_router.py

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from fastapi import APIRouter, Depends, status, HTTPException, Path
1+
from fastapi import APIRouter, Depends, status, HTTPException, Path, Body
22

33
from sqlalchemy.orm import Session
44

@@ -277,13 +277,62 @@ def delete_applicant_application(db: Session = Depends(dependencies.get_db),
277277
return f"Deleted application for job {job_id} for applicant {applicant.id}."
278278

279279

280-
# PATCH /applications/{job_id}_{applicant_id}/review change status to under review
281-
# @router.patch(
282-
# "/applications/review/"
283-
# )
280+
# PATCH /applications/{job_id}_{applicant_id}/ change status
281+
@router.patch(
282+
"/applications/{job_id}_{applicant_id}/",
283+
response_model=user_profile_job_schema.UserProfileJob,
284+
status_code=status.HTTP_200_OK,
285+
tags=["Application"],
286+
summary="PATCH route for a recruiter to change the status of an application.",
287+
description="Change the status of an application for a job and provide optional rejection feedback " \
288+
"for the applicant. The status of an application cannot move backwards. The recruiter must " \
289+
"own the job to be able to change the status of an application.",
290+
response_description="The updated application."
291+
)
292+
def change_application_status(db: Session = Depends(dependencies.get_db),
293+
job_id: int = Path(),
294+
applicant_id: int = Path(),
295+
new_status: application_status_model.ApplicationStatusEnum = Body(),
296+
rejection_feedback: str | None = Body(default=None),
297+
recruiter: user_model.User = Depends(dependencies.get_current_recruiter_user)):
298+
# Check the application exists
299+
application = user_profile_job_crud.get_application_by_user_id_and_job_id(db, applicant_id, job_id)
300+
if application is None:
301+
raise HTTPException(
302+
status_code=status.HTTP_404_NOT_FOUND,
303+
detail=f"Application for job {job_id} and applicant {applicant_id} does not exist."
304+
)
305+
306+
# Check the recruiter owns the job
307+
job = job_crud.get_job_by_id(db, job_id)
308+
309+
if job.user_profile_id != recruiter.id:
310+
raise HTTPException(
311+
status_code=status.HTTP_401_UNAUTHORIZED,
312+
detail=f"Recruiter {recruiter.id} is not authorized to update applications for job " \
313+
"{job_id}."
314+
)
315+
316+
# Check the current status of the application and the new status of the application to see if it is allowed
317+
# The new status of an application must be greater or equal to the current status of an application
318+
# except in the case of REJECTED, which is a final status it can only be equal
319+
can_change_app_status = False
320+
new_application_status_id = application_status_crud.get_application_status_by_name(db, new_status.value).id
321+
322+
if application.application_status.status == application_status_model.ApplicationStatusEnum.rejected.value:
323+
if new_application_status_id == application.application_status_id:
324+
can_change_app_status = True
325+
else:
326+
if new_application_status_id >= application. application_status_id:
327+
can_change_app_status = True
284328

285-
# PATCH /applications/{job_id}_{applicant_id}/further_screening
329+
if not can_change_app_status:
330+
raise HTTPException(
331+
status_code=status.HTTP_400_BAD_REQUEST,
332+
detail=f"Cannot change application status from {application.application_status.status} to "\
333+
f"{new_status.value}."
334+
)
286335

287-
# PATCH /applications/{job_id}_{applicant_id}/offer change status to offer sent
336+
# Update the application status of the application
337+
return user_profile_job_crud.update_applicant_application_status(db, applicant_id, job_id, new_status, rejection_feedback)
288338

289-
# PATCH /applications/{job_id}_{applicant_id}/rejected change status to rejected

backend/schemas/user_profile_job_schema.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class UserProfileJob(UserProfileJobBase):
4444
application_status_id : int
4545
application_submitted_date : date | None
4646
application_reviewed_date : date | None
47+
application_further_screening_date : date | None
4748
application_offer_sent_date : date | None
4849
application_rejected_date : date | None
4950
rejection_feedback : str | None
@@ -59,12 +60,13 @@ class Config:
5960
"job_id": 1,
6061
"application_status_id": 1,
6162
"application_submitted_date": "2023-01-01",
62-
"application_reviewed_date": None,
63-
"application_offer_sent_date": None,
63+
"application_reviewed_date": "2023-01-02",
64+
"application_further_screening_date": "2023-01-02",
65+
"application_offer_sent_date": "2023-01-03",
6466
"application_rejected_date": None,
6567
"application_status": {
6668
"id": 1,
67-
"status": "Application Submitted"
69+
"status": "SUBMITTED"
6870
},
6971
"applicant": {
7072
"user_id": 1,

backend/sql/cyberhire_ddl.sql

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,11 @@ CREATE TABLE IF NOT EXISTS cyberhire."application_status" (
8484

8585
INSERT INTO cyberhire."application_status" (status)
8686
VALUES
87-
('Application Submitted'),
88-
('Application Under Review'),
89-
('Offer Sent'),
90-
('Rejected')
87+
('SUBMITTED'),
88+
('UNDER REVIEW'),
89+
('UNDERGOING FURTHER SCREENING')
90+
('REJECTED'),
91+
('OFFER SENT')
9192
;
9293

9394
-- Create for the user_profile_job table
@@ -97,11 +98,12 @@ CREATE TABLE IF NOT EXISTS cyberhire."user_profile_job" (
9798
application_status_id int4 NOT NULL,
9899
application_submitted_date date NOT NULL,
99100
application_reviewed_date date NULL,
101+
application_further_screening_date date NULL,
100102
application_offer_sent_date date NULL,
101103
application_rejected_date date NULL,
102104
rejection_feedback varchar(2000) NULL,
103105
CONSTRAINT user_profile_job_pkey PRIMARY KEY (user_profile_id, job_id),
104106
CONSTRAINT user_profile_job_fk FOREIGN KEY (user_profile_id) REFERENCES cyberhire."user_profile" (user_id),
105107
CONSTRAINT user_profile_job_fk2 FOREIGN KEY (job_id) REFERENCES cyberhire."job" (id),
106108
CONSTRAINT user_profile_job_fk3 FOREIGN KEY (application_status_id) REFERENCES application_status (id)
107-
);
109+
);

0 commit comments

Comments
 (0)