Coverage for employers/routes_employers.py: 85%

119 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-05-05 14:02 +0000

1"""Routes for employers module""" 

2 

3from datetime import datetime 

4from html import escape 

5import uuid 

6from flask import ( 

7 flash, 

8 jsonify, 

9 redirect, 

10 request, 

11 render_template, 

12 send_file, 

13 session, 

14 url_for, 

15) 

16from itsdangerous import URLSafeSerializer 

17from core import handlers, shared 

18from course_modules.models import Module 

19from courses.models import Course 

20from opportunities.models import Opportunity 

21from skills.models import Skill 

22from .models import Employers 

23 

24 

25def add_employer_routes(app): 

26 """Add employer routes.""" 

27 

28 @app.route("/employers/login", methods=["GET", "POST"]) 

29 def employer_login(): 

30 handlers.clear_session_save_theme() 

31 if request.method == "POST": 

32 email = request.form.get("email") 

33 return Employers().employer_login(email) 

34 

35 return render_template("employers/employer_login.html") 

36 

37 @app.route("/employers/home", methods=["GET"]) 

38 @handlers.employers_login_required 

39 def employer_home(employer): 

40 deadline_info = Employers().get_deadlines_for_employer_dashboard() 

41 deadline_name, deadline_date, deadline_task = deadline_info 

42 

43 formatted_date = ( 

44 datetime.strptime(deadline_date, "%Y-%m-%d").strftime("%d-%m-%Y") 

45 if deadline_date 

46 else None 

47 ) 

48 from app import DEADLINE_MANAGER 

49 

50 deadline_type = DEADLINE_MANAGER.get_deadline_type() 

51 if deadline_type == 3: 

52 deadline_task = "Your ranking is complete. To make changes, visit the 'Opportunities' page and click 'Rank' to update your preferences." 

53 

54 return render_template( 

55 "employers/employer_home.html", 

56 deadline_name=deadline_name, 

57 deadline_date=formatted_date, 

58 deadline_task=deadline_task, 

59 employer=employer, 

60 user_type="employer", 

61 deadline_type=deadline_type, 

62 ) 

63 

64 @app.route("/employers/otp", methods=["POST"]) 

65 def employer_otp(): 

66 

67 if "employer" not in session: 

68 return jsonify({"error": "Employer not logged in."}), 400 

69 otp_serializer = URLSafeSerializer(str(shared.getenv("SECRET_KEY", "secret"))) 

70 if "OTP" not in session: 

71 return jsonify({"error": "OTP not sent."}), 400 

72 if request.form.get("otp") != otp_serializer.loads(session["OTP"]): 

73 return jsonify({"error": "Invalid OTP."}), 400 

74 

75 return Employers().start_session() 

76 

77 @app.route("/employers/add_employer", methods=["GET", "POST"]) 

78 @handlers.login_required 

79 def add_employer(): 

80 if request.method == "POST": 

81 employer = { 

82 "_id": uuid.uuid4().hex, 

83 "company_name": escape(request.form.get("company_name")), 

84 "email": escape(request.form.get("email")), 

85 } 

86 return Employers().register_employer(employer) 

87 return render_template( 

88 "employers/add_employer.html", user_type="admin", page="employers" 

89 ) 

90 

91 @app.route("/employers/search", methods=["GET"]) 

92 @handlers.login_required 

93 def search_employers(): 

94 employers = Employers().get_employers() 

95 return render_template( 

96 "employers/search_employers.html", 

97 user_type="admin", 

98 employers=employers, 

99 page="employers", 

100 ) 

101 

102 @app.route("/employers/update_employer", methods=["GET", "POST"]) 

103 @handlers.login_required 

104 def update_employer(): 

105 from app import DATABASE_MANAGER 

106 

107 employer_id = request.args.get("employer_id") # Get employer_id from URL query 

108 if request.method == "POST": 

109 employer_id = request.form.get("employer_id") 

110 

111 update_data = { 

112 "company_name": escape(request.form.get("company_name")), 

113 "email": escape(request.form.get("email")), 

114 } 

115 return Employers().update_employer(employer_id, update_data) 

116 

117 employer = DATABASE_MANAGER.get_one_by_id("employers", employer_id) 

118 if not employer: 

119 flash("Employer not found", "error") 

120 return redirect(url_for("search_employers")) 

121 

122 return render_template( 

123 "employers/update_employer.html", 

124 user_type="admin", 

125 employer=employer, 

126 page="employers", 

127 ) 

128 

129 @app.route("/employers/delete_employer", methods=["POST"]) 

130 @handlers.login_required 

131 def delete_employer(): 

132 data = request.get_json() # Get JSON data from the request 

133 employer_id = data.get("employer_id") # Extract employer_id from JSON 

134 

135 if not employer_id: 

136 return jsonify({"error": "Employer ID is required"}), 400 

137 

138 return Employers().delete_employer_by_id(employer_id) 

139 

140 @app.route("/employers/rank_students", methods=["GET", "POST"]) 

141 @handlers.employers_login_required 

142 def employers_rank_students(_stuff): 

143 from app import DEADLINE_MANAGER 

144 

145 if ( 

146 DEADLINE_MANAGER.is_past_opportunities_ranking_deadline() 

147 and "employer" in session 

148 ): 

149 return render_template( 

150 "employers/past_deadline.html", 

151 data=( 

152 f"Ranking deadline has passed as of " 

153 f"{DEADLINE_MANAGER.get_opportunities_ranking_deadline()}" 

154 ), 

155 referrer=request.referrer, 

156 employer=session["employer"], 

157 user_type="employer", 

158 deadline_type=DEADLINE_MANAGER.get_deadline_type(), 

159 ) 

160 opportunity_id = request.args.get("opportunity_id") 

161 if not opportunity_id: 

162 return jsonify({"error": "Need opportunity ID."}), 400 

163 opportunity = Opportunity().get_opportunity_by_id(opportunity_id) 

164 if session["employer"]["_id"] != opportunity["employer_id"]: 

165 return jsonify({"error": "Employer does not own this opportunity."}), 400 

166 if not DEADLINE_MANAGER.is_past_student_ranking_deadline(): 

167 return render_template( 

168 "employers/past_deadline.html", 

169 data=( 

170 "Student ranking deadline must have passed before you can start, " 

171 f"wait till {DEADLINE_MANAGER.get_student_ranking_deadline()}" 

172 ), 

173 referrer=request.referrer, 

174 employer=session["employer"], 

175 ) 

176 if request.method == "POST": 

177 ranks = request.form.get("ranks").split(",") 

178 preferences = [a[5:].strip() for a in ranks] 

179 if preferences == [""]: 

180 preferences = [] 

181 return Opportunity().rank_preferences(opportunity_id, preferences) 

182 valid_students = Opportunity().get_valid_students(opportunity_id) 

183 return render_template( 

184 "opportunities/employer_rank_students.html", 

185 opportunity_id=opportunity_id, 

186 students=valid_students, 

187 get_course_name=Course().get_course_name_by_id, 

188 get_module_name=Module().get_module_name_by_id, 

189 get_skill_name=Skill().get_skill_name_by_id, 

190 user_type="employer", 

191 deadline_type=DEADLINE_MANAGER.get_deadline_type(), 

192 ) 

193 

194 @app.route("/employers/upload", methods=["GET", "POST"]) 

195 @handlers.login_required 

196 def upload_employers(): 

197 """Route for uploading employers""" 

198 if request.method == "POST": 

199 file = request.files["file"] 

200 if not file: 

201 return jsonify({"error": "No file provided"}), 400 

202 if not handlers.allowed_file(file.filename, ["xlsx", "xls"]): 

203 return jsonify({"error": "Invalid file type"}), 400 

204 

205 return Employers().upload_employers(file) 

206 

207 return render_template( 

208 "employers/upload.html", user_type="admin", page="employers" 

209 ) 

210 

211 @app.route("/employers/delete_all", methods=["DELETE"]) 

212 @handlers.login_required 

213 def delete_all_employers(): 

214 """Route to delete all employers""" 

215 return Employers().delete_all_employers() 

216 

217 @app.route("/employers/download_template", methods=["GET"]) 

218 @handlers.login_required 

219 def download_employers_template(): 

220 """Route to download employers template""" 

221 return send_file( 

222 "data_model_upload_template/employers_template.xlsx", as_attachment=True 

223 ) 

224 

225 @app.route("/employers/download_all", methods=["GET"]) 

226 @handlers.login_required 

227 def download_all_employers(): 

228 """Route to download all employers""" 

229 return Employers().download_all_employers()