Skip to content

Commit

Permalink
Merge pull request #157 from yashlm/main
Browse files Browse the repository at this point in the history
added past hires
  • Loading branch information
yashlm authored Jun 19, 2024
2 parents dc351f4 + 7eb3ac0 commit efc875a
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 12 deletions.
58 changes: 58 additions & 0 deletions application/db.student.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,64 @@ func createEventStudents(ctx *gin.Context, eventStudents *[]EventStudent) error
return tx.Error
}

func getCompanyRecruitmentStats(ctx *gin.Context, cid uint, stats *[]statsResponse) error {
tx := db.WithContext(ctx).Model(&EventStudent{}).
Joins("JOIN proforma_events ON proforma_events.name IN ? AND proforma_events.id = event_students.proforma_event_id", []EventType{Recruited, PIOPPOACCEPTED}).
Joins("JOIN proformas ON proformas.id = proforma_events.proforma_id AND proformas.company_recruitment_cycle_id = ?", cid).
Select("event_students.student_recruitment_cycle_id, proformas.company_name, proformas.profile ,proforma_events.name as type").
Order("event_students.student_recruitment_cycle_id").
Find(stats)
return tx.Error
}
func fetchCompanyRecruitCount(ctx *gin.Context, cids []uint) (map[uint]int, error) {
resultCounts := make(map[uint]int)

var stats []companyRecruitResponce
tx := db.WithContext(ctx).Model(&EventStudent{}).
Joins("JOIN proforma_events ON proforma_events.name IN ? AND proforma_events.id = event_students.proforma_event_id", []EventType{Recruited, PIOPPOACCEPTED}).
Joins("JOIN proformas ON proformas.id = proforma_events.proforma_id").
Where("proformas.company_recruitment_cycle_id IN ?", cids).
Select("proformas.company_recruitment_cycle_id, COUNT(*) as count").
Group("proformas.company_recruitment_cycle_id").
Order("proformas.company_recruitment_cycle_id").
Find(&stats)

if tx.Error != nil {
return nil, tx.Error
}

// Populate resultCounts map
for _, stat := range stats {
resultCounts[stat.CompanyRecruitmentCycleID] = stat.Count
}

return resultCounts, nil
}

func fetchCompanyPPOCount(ctx *gin.Context, cids []uint) (map[uint]int, error) {
resultCounts := make(map[uint]int)

var stats []companyRecruitResponce
tx := db.WithContext(ctx).Model(&EventStudent{}).
Joins("JOIN proforma_events ON proforma_events.name IN ? AND proforma_events.id = event_students.proforma_event_id", []EventType{PIOPPOACCEPTED}).
Joins("JOIN proformas ON proformas.id = proforma_events.proforma_id").
Where("proformas.company_recruitment_cycle_id IN ?", cids).
Select("proformas.company_recruitment_cycle_id, COUNT(*) as count").
Group("proformas.company_recruitment_cycle_id").
Order("proformas.company_recruitment_cycle_id").
Find(&stats)

if tx.Error != nil {
return nil, tx.Error
}

for _, stat := range stats {
resultCounts[stat.CompanyRecruitmentCycleID] = stat.Count
}

return resultCounts, nil
}

func getRecruitmentStats(ctx *gin.Context, rid uint, stats *[]statsResponse) error {
tx := db.WithContext(ctx).Model(&EventStudent{}).
Joins("JOIN proforma_events ON proforma_events.name IN ? AND proforma_events.id = event_students.proforma_event_id", []EventType{Recruited, PIOPPOACCEPTED}).
Expand Down
2 changes: 2 additions & 0 deletions application/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func AdminRouter(mail_channel chan mail.Mail, r *gin.Engine) {
admin.DELETE("event/:eid/student/:sid", deleteStudentFromEventHandler)

admin.GET("/company/:cid/proforma", getProformaByCompanyHandler)
admin.GET("/company/:cid/stats", getCompanyRecruitStatsHandler)
admin.POST("/company/count", fetchCompanyRecruitCountHandler)

admin.GET("/proforma", getAllProformasHandler)
admin.POST("/proforma", postProformaHandler)
Expand Down
79 changes: 79 additions & 0 deletions application/stats.recruitment.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,85 @@ type statsRecruitmentResponse struct {
Type string `json:"type"`
}

type companyRecruitResponce struct {
CompanyRecruitmentCycleID uint `json:"company_recruitment_cycle_id"`
Count int `json:"count"`
}

func fetchCompanyRecruitCountHandler(c *gin.Context) {
var cids []uint

if err := c.ShouldBindJSON(&cids); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request format"})
return
}

recruitCounts, err := fetchCompanyRecruitCount(c, cids)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"})
return
}
ppoCounts, err := fetchCompanyPPOCount(c, cids)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"})
return
}

c.JSON(http.StatusOK, gin.H{"recruitCounts": recruitCounts, "ppoCount": ppoCounts})
}

func getCompanyRecruitStatsHandler(ctx *gin.Context) {
cid, err := util.ParseUint(ctx.Param("cid"))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

var stats []statsResponse
err = getCompanyRecruitmentStats(ctx, cid, &stats)

if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var srids []uint
for _, stat := range stats {
srids = append(srids, stat.StudentRecruitmentCycleID)
}

var students []rc.StudentRecruitmentCycle
err = rc.FetchStudentBySRID(ctx, srids, &students)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}

var studentsMap = make(map[uint]*rc.StudentRecruitmentCycle)
for i := range students {
studentsMap[students[i].ID] = &students[i]
}

var studentResponse []statsRecruitmentResponse
for _, stat := range stats {
student := studentsMap[stat.StudentRecruitmentCycleID]
res := statsRecruitmentResponse{
ID: student.ID,
Name: student.Name,
Email: student.Email,
RollNo: student.RollNo,
ProgramDepartmentID: student.ProgramDepartmentID,
SecondaryProgramDepartmentID: student.SecondaryProgramDepartmentID,
CompanyName: stat.CompanyName,
Profile: stat.Profile,
Type: stat.Type,
}
studentResponse = append(studentResponse, res)
}

ctx.JSON(http.StatusOK, gin.H{"student": studentResponse})

}

func getStatsHandler(ctx *gin.Context) {
rid, err := util.ParseUint(ctx.Param("rid"))
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion mail/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ func (mail *Mail) BuildMessage() []byte {

message.WriteString(msg)

bodyWithLineBreaks := strings.ReplaceAll(mail.Body, "\n", "<br>")

tmpl := template.Must(template.New("Template").Parse(DefaultTemplate))
err := tmpl.Execute(&message, TemplateData{
Subject: mail.Subject,
Body: mail.Body,
Body: bodyWithLineBreaks,
})
if err != nil {
logrus.Errorf("Error executing email template: %v", err)
Expand Down
18 changes: 9 additions & 9 deletions mail/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ const (
<html dir="ltr" lang="en">
<head></head>
<body style="background-color:#ffffff;margin:0 auto;font-family:-apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif">
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="max-width:37.5em;margin:0 auto;padding:0px 20px">
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="width:100%;margin:0 auto;padding:0px 20px">
<tbody>
<tr style="width:100%">
<td>
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-top:10px">
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation" style="margin-top:10px;width:100%">
<tbody>
<tr>
<td><img alt="Recruitment Automation System &lt;br /&gt; Indian Institute of Technology, Kanpur" height="75" src="https://i.ibb.co/h7HMySr/Screenshot-from-2024-04-06-07-02-51.png" style="display:block;outline:none;border:none;text-decoration:none" width="475" /></td>
</tr>
</tbody>
</table>
<h1 style="color:#1d1c1d;font-size:36px;font-weight:700;margin:30px 0;padding:0;line-height:42px">{{.Subject}}</h1>
<p style="font-size:24px;line-height:28px;margin:16px 0;margin-bottom:30px">{{.Body}}<br></br></p>
<p style="font-size:16px;line-height:24px;margin:16px 0;color:#000">This is an auto-generated email. Please do not reply.</p>
<h1 style="color:#1d1c1d;font-size:24px;font-weight:700;margin:30px 0;padding:0;line-height:28px">{{.Subject}}</h1>
<p style="font-size:16px;line-height:20px;margin:16px 0;margin-bottom:30px;white-space:pre-wrap">{{.Body}}</p>
<p style="font-size:12px;line-height:16px;margin:16px 0;color:#000">This is an auto-generated email. Please do not reply.</p>
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation">
<tbody>
<tr>
Expand All @@ -36,9 +36,9 @@ const (
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation">
<tbody style="width:100%">
<tr style="width:100%">
<td data-id="__react-email-column"><a href="https://twitter.com/IITKanpur" style="color:#067df7;text-decoration:none" target="_blank"><img alt="Twitter" height="32" src="https://th.bing.com/th/id/OIP.YGJYM4pqXxVMHzPYfdLumgHaHa?rs=1&amp;pid=ImgDetMain" style="display:inline;outline:none;border:none;text-decoration:none;margin-left:32px" width="32" /></a></td>
<td data-id="__react-email-column"><a href="https://www.facebook.com/spo.iitkanpur/" style="color:#067df7;text-decoration:none" target="_blank"><img alt="Facebook" height="32" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/2021_Facebook_icon.svg/2048px-2021_Facebook_icon.svg.png" style="display:inline;outline:none;border:none;text-decoration:none;margin-left:32px" width="32" /></a></td>
<td data-id="__react-email-column"><a href="https://www.linkedin.com/company/students-placement-office-iit-kanpur/" style="color:#067df7;text-decoration:none" target="_blank"><img alt="LinkedIn" height="32" src="https://static-00.iconduck.com/assets.00/linkedin-icon-1024x1024-net2o24e.png" style="display:inline;outline:none;border:none;text-decoration:none;margin-left:32px" width="32" /></a></td>
<td data-id="__react-email-column"><a href="https://twitter.com/IITKanpur" style="color:#067df7;text-decoration:none" target="_blank"><img alt="Twitter" height="32" src="https://th.bing.com/th/id/OIP.YGJYM4pqXxVMHzPYfdLumgHaHa?rs=1&amp;pid=ImgDetMain" style="display:inline;outline:none;border:none;text-decoration:none;margin-left:16px" width="32" /></a></td>
<td data-id="__react-email-column"><a href="https://www.facebook.com/spo.iitkanpur/" style="color:#067df7;text-decoration:none" target="_blank"><img alt="Facebook" height="32" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b8/2021_Facebook_icon.svg/2048px-2021_Facebook_icon.svg.png" style="display:inline;outline:none;border:none;text-decoration:none;margin-left:16px" width="32" /></a></td>
<td data-id="__react-email-column"><a href="https://www.linkedin.com/company/students-placement-office-iit-kanpur/" style="color:#067df7;text-decoration:none" target="_blank"><img alt="LinkedIn" height="32" src="https://static-00.iconduck.com/assets.00/linkedin-icon-1024x1024-net2o24e.png" style="display:inline;outline:none;border:none;text-decoration:none;margin-left:16px" width="32" /></a></td>
</tr>
</tbody>
</table>
Expand All @@ -57,7 +57,7 @@ const (
<table align="center" width="100%" border="0" cellPadding="0" cellSpacing="0" role="presentation">
<tbody>
<tr>
<td><a href="https://spo.iitk.ac.in/" rel="noopener noreferrer" style="color:#b7b7b7;text-decoration:underline" target="_blank">Website</a> | <a href="https://placement.iitk.ac.in/" rel="noopener noreferrer" style="color:#b7b7b7;text-decoration:underline" target="_blank">RAS Portal</a> | <a href="https://phdplacement.iitk.ac.in/" rel="noopener noreferrer" style="color:#b7b7b7;text-decoration:underline" target="_blank">PhD Portal</a>
<td><a href="https://spo.iitk.ac.in/" rel="noopener noreferrer" style="color:#b7b7b7;text-decoration:underline;font-size:14px;" target="_blank">Website</a> | <a href="https://placement.iitk.ac.in/" rel="noopener noreferrer" style="color:#b7b7b7;text-decoration:underline;font-size:14px;" target="_blank">RAS Portal</a> | <a href="https://phdplacement.iitk.ac.in/" rel="noopener noreferrer" style="color:#b7b7b7;text-decoration:underline;font-size:14px;" target="_blank">PhD Portal</a>
<p style="font-size:12px;line-height:15px;margin:16px 0;color:#b7b7b7;text-align:left;margin-bottom:50px">©2024 Recruitment Automation System. <br />Students&#x27; Placement Office, IIT Kanpur <br /><br />All rights reserved.</p>
</td>
</tr>
Expand Down
4 changes: 2 additions & 2 deletions ras/hello.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ func PlaceHolderController(c *gin.Context) {

func MailController(mail_channel chan mail.Mail) gin.HandlerFunc {
return func(c *gin.Context) {
mail_channel <- mail.GenerateMail("harshitr20@iitk.ac.in", "Test Mail", "Hello World!")
mail_channel <- mail.GenerateMails([]string{"[email protected]", "ias@iitk.ac.in"}, "Test Mail to multiple ppl", "Hello Worlds!")
mail_channel <- mail.GenerateMail("yashc22@iitk.ac.in", "Test Mail", "Hello World!")
mail_channel <- mail.GenerateMails([]string{"[email protected]", "bmerchant22@iitk.ac.in"}, "Test Mail to multiple ppl", "Hello Worlds!")
c.JSON(http.StatusOK, gin.H{"message": "Mail sent"})
}
}
40 changes: 40 additions & 0 deletions rc/admin.company.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,46 @@ type addNewCompanyRequest struct {
Comments string `json:"comments"`
}

type StatResponse struct {
ID uint `json:"id"`
RecruitmentCycleID uint `json:"recruitment_cycle_id"`
Type string `json:"type"`
Phase string `json:"phase"`
}
type CompanyAllRecruitmentCycle struct {
ID uint `json:"id"`
RecruitmentCycleID uint `json:"recruitment_cycle_id"`
Type string `json:"type"`
Phase string `json:"phase"`
}

func getCompanyAllRCID(ctx *gin.Context) {
cid, err := util.ParseUint(ctx.Param("cid"))
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var stats []CompanyAllRecruitmentCycle
err = fetchCompanyAllRecruitmentCycles(ctx, cid, &stats)
if err != nil {
ctx.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
var countResponse []CompanyAllRecruitmentCycle

for _, stat := range stats {
countResponse = append(countResponse, CompanyAllRecruitmentCycle{
ID: stat.ID,
RecruitmentCycleID: stat.RecruitmentCycleID,
Type: stat.Type,
Phase: stat.Phase,
})
}

ctx.JSON(http.StatusOK, countResponse)

}

func postNewCompanyHandler(ctx *gin.Context) {
var addNewCompany addNewCompanyRequest

Expand Down
11 changes: 11 additions & 0 deletions rc/db.company.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,17 @@ func deleteRCCompany(ctx *gin.Context, cid uint) error {
return tx.Error
}

func fetchCompanyAllRecruitmentCycles(ctx *gin.Context, companyID uint, stats *[]CompanyAllRecruitmentCycle) error {
tx := db.WithContext(ctx).
Table("company_recruitment_cycles").
Select("company_recruitment_cycles.id, company_recruitment_cycles.recruitment_cycle_id, recruitment_cycles.type, recruitment_cycles.phase").
Joins("JOIN recruitment_cycles ON company_recruitment_cycles.recruitment_cycle_id = recruitment_cycles.id").
Where("company_recruitment_cycles.company_id = ?", companyID).
Find(stats)

return tx.Error
}

func FetchCompanyHistory(ctx *gin.Context, companyID uint, companyHistory *[]CompanyHistory) error {
tx := db.WithContext(ctx).
Table("company_recruitment_cycles").
Expand Down
1 change: 1 addition & 0 deletions rc/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func AdminRouter(mail_channel chan mail.Mail, r *gin.Engine) {
admin.GET("/company/:cid", getCompanyHandler)
admin.DELETE("/company/:cid", deleteCompanyHandler)
admin.GET("/company/:cid/history", getCompanyHistoryHandler)
admin.GET("/company/:cid/ids", getCompanyAllRCID)

admin.GET("/student", getAllStudentsHandler)

Expand Down

0 comments on commit efc875a

Please sign in to comment.