diff --git a/fixtures/internships.groovy b/fixtures/internships.groovy index b5b6fa2..75c1a90 100644 --- a/fixtures/internships.groovy +++ b/fixtures/internships.groovy @@ -9,6 +9,6 @@ include "companies" include "millesimes" fixture { - firstInternship(Internship, subject: "First Internship", beginAt: new Date(), isApproval: true, student: nadirRole, academicTutor: hclRole, companyTutor: jobsRole, company: apple, report: firstInternshipReport, convocation: firstConvocation, length:6, millesime:m2009) - secondInternship(Internship, subject: "Second Internship", beginAt: new Date(), isApproval: true, student: thomasRole, academicTutor: hclRole, companyTutor: balmerRole, company: microsoft, report: secondInternshipReport, convocation: secondConvocation, length:6, millesime:m2008) + firstInternship(Internship, subject: "First Internship", beginAt: new Date(), isApproval: false, student: nadirRole, academicTutor: hclRole, companyTutor: jobsRole, company: apple, report: firstInternshipReport, convocation: firstConvocation, length:6, millesime:m2009) + secondInternship(Internship, subject: "Second Internship", beginAt: new Date(), isApproval: false, reason: "it's not a good internship", student: alexisRole, academicTutor: hclRole, companyTutor: balmerRole, company: microsoft, report: secondInternshipReport, convocation: secondConvocation, length:6, millesime:m2008) } diff --git a/fixtures/users.groovy b/fixtures/users.groovy index 3ca8312..ce8ab12 100644 --- a/fixtures/users.groovy +++ b/fixtures/users.groovy @@ -48,7 +48,7 @@ fixture { lastName : "Maurel" , address : thomasAddress, phone : "0102030405", - authorities : [thomasRole, adminRole], + authorities : [adminRole], showEmail : true ) diff --git a/grails-app/controllers/me/hcl/seekin/Internship/InternshipController.groovy b/grails-app/controllers/me/hcl/seekin/Internship/InternshipController.groovy index 773dc1d..94b3099 100644 --- a/grails-app/controllers/me/hcl/seekin/Internship/InternshipController.groovy +++ b/grails-app/controllers/me/hcl/seekin/Internship/InternshipController.groovy @@ -10,10 +10,14 @@ import me.hcl.seekin.Auth.UserController import me.hcl.seekin.Auth.Role.External import me.hcl.seekin.Util.Address import me.hcl.seekin.Company +import me.hcl.seekin.Formation.Millesime +import me.hcl.seekin.Formation.Promotion +import org.hibernate.LockMode class InternshipController { - - def dateService + + def authenticateService + def sessionFactory def index = { redirect(action: "list", params: params) } @@ -21,19 +25,70 @@ class InternshipController { static allowedMethods = [save: "POST", update: "POST", delete: "POST"] def list = { + + /* Controls if some internships which wait for Validation are validated by examinate params */ + def internship + params.each { + if(it.key.contains("validate_") && it.value == "on") { + /* Get the offer and do the mofification before saving */ + internship = Internship.get(it.key.split("_")[1].toInteger()) + internship.isApproval = true + internship.save(flush:true) + } + } + + /* If the user is not logged in, we redirect him at the index of seekin */ + def status = new HashSet() + if(!authenticateService.isLoggedIn()) { + redirect(controller: "user", action: "index") + } + else { + if(authenticateService.ifAnyGranted("ROLE_ADMIN,ROLE_FORMATIONMANAGER")) { + //status.add 'internship.validated' + //status.add 'internship.unvalidated' + //status.add 'internship.waitForValidation' + Internship.list().each { + status.add it.getStatus(new Staff()) + } + } + else if(authenticateService.ifAnyGranted("ROLE_STAFF")) { + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + def statusStaff = userInstance.authorities.find { + it.authority == "ROLE_STAFF" + } + Internship.list().each { + if(it.getStatus(new Staff()) == 'internship.validated') + status.add it.getStatus(new Staff()) + if(it.getStatus(statusStaff) == 'internship.mine') + status.add it.getStatus(statusStaff) + } + //status.add 'internship.validated' + //status.add 'internship.mine' + + } + else { + Internship.list().each { + if(it.getStatus(new Staff()) == 'internship.validated') + status.add 'internship.validated' + } + } + + render(view: "list", model: [status: status]) + } } def create = { def staff = Staff.list().collect { [ id: it.id, - value: it.user.firstName + " " + it.user.lastName + value: it.user?.firstName + " " + it.user?.lastName ] } def student = Student.list().collect { [ id: it.id, - value: it.user.firstName + " " + it.user.lastName + value: it.user?.firstName + " " + it.user?.lastName ] } def offer = Offer.list().collect { @@ -52,6 +107,7 @@ class InternshipController { internshipInstance.length = offerFromSelection.length internshipInstance.company = offerFromSelection.company internshipInstance.fromOffer = true + internshipInstance.description = offerFromSelection.description } else { internshipInstance = new Internship() @@ -97,6 +153,16 @@ class InternshipController { internshipInstance.properties = params internshipInstance.company = company + internshipInstance.millesime = Millesime.getCurrent() + if(authenticateService.ifAnyGranted("ROLE_STUDENT")) { + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + def statusStudent = userInstance.authorities.find { + it.authority == "ROLE_STUDENT" + } + internshipInstance.student = statusStudent + internshipInstance.isApproval = false + } if (!internshipInstance.hasErrors() && internshipInstance.save()) { flash.message = "internship.created" flash.args = [internshipInstance.id] @@ -117,7 +183,7 @@ class InternshipController { redirect(action: "list") } else { - return [internshipInstance: internshipInstance, beginAt: dateService.formatDate(request, internshipInstance.beginAt), convocation: dateService.formatDate(request, internshipInstance?.convocation?.date)] + return [internshipInstance: internshipInstance] } } @@ -130,7 +196,7 @@ class InternshipController { redirect(action: "list") } else { - return [internshipInstance: internshipInstance, convocation: dateService.formatDate(request, internshipInstance?.convocation?.date)] + return [internshipInstance: internshipInstance] } } @@ -191,9 +257,57 @@ class InternshipController { } def dataTableDataAsJSON = { - def list = Internship.list(params) + def list = [] + def status = new HashMap() def ret = [] response.setHeader("Cache-Control", "no-store") + if(authenticateService.ifAnyGranted("ROLE_ADMIN,ROLE_FORMATIONMANAGER")) { + Internship.list().each() { + it.each() { it2 -> + if(it2.getStatus(new Staff()) == params.status) { + list.add it2 + } + } + } + } + if(authenticateService.ifAnyGranted("ROLE_STUDENT")) { + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + Internship.list().each() { + it.each() { it2 -> + if(it2.getStatus(new Staff()) == params.status && it2.student.user == userInstance) { + list.add it2 + } + } + } + } + if(authenticateService.ifAnyGranted("ROLE_EXTERNAL")) { + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + Internship.list().each() { + it.each() { it2 -> + if(it2.getStatus(new Staff()) == params.status && it2.companyTutor.user == userInstance) { + list.add it2 + } + } + } + } + if(authenticateService.ifAnyGranted("ROLE_STAFF")) { + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + def statusStaff = userInstance.authorities.find { + it.authority == "ROLE_STAFF" + } + println statusStaff + Internship.list().each() { + it.each() { it2 -> + if(it2.getStatus(statusStaff) == params.status && (it2.companyTutor.user == userInstance || it2.isApproval == true)) { + println params + list.add it2 + } + } + } + } list.each { ret << [ @@ -209,7 +323,7 @@ class InternshipController { } def data = [ - totalRecords: Internship.count(), + totalRecords: list.size(), results: ret ] diff --git a/grails-app/controllers/me/hcl/seekin/Internship/OfferController.groovy b/grails-app/controllers/me/hcl/seekin/Internship/OfferController.groovy index d2b99eb..198521a 100644 --- a/grails-app/controllers/me/hcl/seekin/Internship/OfferController.groovy +++ b/grails-app/controllers/me/hcl/seekin/Internship/OfferController.groovy @@ -6,6 +6,8 @@ import grails.converters.JSON import me.hcl.seekin.Company import org.hibernate.LockMode import me.hcl.seekin.Formation.Promotion +import org.codehaus.groovy.grails.plugins.springsecurity.Secured +import me.hcl.seekin.Formation.Millesime class OfferController { @@ -19,20 +21,25 @@ class OfferController { def list = { + /* Controls if some offers which wait for Validation are validated by examinate params */ def offer params.each { if(it.key.contains("validate_") && it.value == "on") { + /* Get the offer and do the mofification before saving */ offer = Offer.get(it.key.split("_")[1].toInteger()) offer.validated = true offer.save(flush:true) } } - + + /* If the user is not logged in, we redirect him at the index of seekin */ def status if(!authenticateService.isLoggedIn()) { redirect(controller: "user", action: "index") } + /* Build a status list depending on roles */ else { + /* If the user is the admin or a formation manager, status we want to display are all the status affiliated to a current offer */ if(authenticateService.ifAnyGranted("ROLE_ADMIN,ROLE_FORMATIONMANAGER")) { status = new HashSet() Promotion.getCurrents().offers.each() { @@ -41,18 +48,24 @@ class OfferController { } } } - else if(authenticateService.ifAnyGranted("ROLE_EXTERNAL")) { + /* If the user is an external or a member staff, status we want to display are all the status affiliated to the offers created by the current user */ + else if(authenticateService.ifAnyGranted("ROLE_EXTERNAL,ROLE_STAFF")) { def userInstance = authenticateService.userDomain() sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) status = new HashSet() Promotion.getCurrents().offers.each() { it.each() { it2 -> - if(it2.author.toString() == userInstance.toString()) { + if(it2?.author.toString() == userInstance.toString()) { status.add it2.getStatus() } } } + /* If the user is staff member we add the status offer.validate to aim the possibility of viewing all validated offers */ + if(authenticateService.ifAnyGranted("ROLE_STAFF")) { + status.add 'offer.validated' + } } + /* If we are in this section the user is a student and will only see validated offers */ else status = ['offer.validated'] @@ -60,26 +73,44 @@ class OfferController { } } + @Secured(['ROLE_ADMIN','ROLE_FORMATIONMANAGER','ROLE_STAFF','ROLE_EXTERNAL']) def create = { def offerInstance = new Offer() offerInstance.properties = params - return [offerInstance: offerInstance] + /* Build the list with all current promotions for the select markup */ + def promotionInstance = Promotion.getCurrents().collect { + [ + id: it.id, + value: it.toString() + ] + } + return [offerInstance: offerInstance, promotionInstance: promotionInstance] } def save = { + /* Offer creation need a company so we verify if the company type by the user exists and create and save it if not */ def company if(Company.countByName(params.companyName) == 0) { company = new Company() company.name = params.companyName company.save() } + /* If the company already exists we get it on company variable */ else { company = Company.findByName(params.companyName) } + /* We get the user logged in in userInstance to identifiate the author */ + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + + /* Build the offer with correct parameter and save it*/ def offerInstance = new Offer(params) offerInstance.company = company + offerInstance.validated = false + offerInstance.assignated = false + offerInstance.author = userInstance if (!offerInstance.hasErrors() && offerInstance.save()) { flash.message = "offer.created" flash.args = [offerInstance.id] @@ -92,29 +123,97 @@ class OfferController { } def show = { + /* We get the user logged in to verify if he is authorized to show an offer */ + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + Boolean showable = false + + /* Get the offer with id parameter */ def offerInstance = Offer.get(params.id) - if (!offerInstance) { + /* If the user have an external role, he is allowed to show only offers which he had created */ + if(authenticateService.ifAnyGranted("ROLE_EXTERNAL")) { + if(offerInstance?.author == userInstance) { + showable = true + } + } + /* If the user is the administrator, he can show all offers */ + else if(authenticateService.ifAnyGranted("ROLE_ADMIN")) { + showable = true + } + /* If the user is a staff's member, he is allowed to show offers which he had created and offers that are validated */ + else if(authenticateService.ifAnyGranted("ROLE_STAFF")) { + if(offerInstance?.author == userInstance || (offerInstance.validated == true && offerInstance.assignated == false)) { + showable = true + } + } + /* If the user is a student, he can show all offers which are validated and correspond to his promotion */ + else if(authenticateService.ifAnyGranted("ROLE_STUDENT")) { + if(offerInstance?.validated == true && offerInstance?.assignated == false) { + def student = userInstance.authorities.find { + it.getRoleName() == "ROLE_STUDENT" + def currentPromo = Promotion.getCurrentForStudent(it) + if(offerInstance.promotions.contains(currentPromo)) { + showable = true + } + } + } + } + + /* If the offer doesn't exist or is not showable, we return a flash message */ + if (!offerInstance || !showable) { flash.message = "offer.not.found" flash.args = [params.id] flash.defaultMessage = "Offer not found with id ${params.id}" redirect(action: "list") } - else { + /* Else we return our instance */ + else if(showable) { return [offerInstance: offerInstance] } } + @Secured(['ROLE_EXTERNAL','ROLE_FORMATIONMANAGER','ROLE_STAFF','ROLE_ADMIN']) def edit = { + /* We get the user logged in to verify if he is authorized to edit an offer */ + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) + Boolean editable = false + + /* Get the offer with id parameter */ def offerInstance = Offer.get(params.id) - if (!offerInstance) { + def promotionInstance + /* If the user is the author of the offer or the administrator */ + if(offerInstance?.author == userInstance || authenticateService.ifAnyGranted("ROLE_ADMIN")) { + /* Build a list of the current promotion */ + promotionInstance = Promotion.getCurrents().collect { + [ + id: it.id, + value: it.toString() + ] + } + /* If the offer is not validated, we verify if the offer is associate to a current promotion */ + if (offerInstance?.validated == false) { + def currentPromo = offerInstance.promotions.find { + it.millesime == Millesime.getCurrent() + } + if(currentPromo != null) { + editable = true + } + } + } + /* If the offer is editable, reason is set to null and the status will be waitForValidation */ + if(editable) { + offerInstance.reason = null + return [offerInstance: offerInstance, promotionInstance: promotionInstance] + } + /* Else we return a flash message */ + else { flash.message = "offer.not.found" flash.args = [params.id] flash.defaultMessage = "Offer not found with id ${params.id}" redirect(action: "list") } - else { - return [offerInstance: offerInstance] - } + } def update = { @@ -173,11 +272,30 @@ class OfferController { } } + /* It is used when an offer is deny by the administrator */ + def deny = { + /* Get the offer and set reason with params.reason before saving and redirect the user to list */ + def offerInstance = Offer.get(params.id) + if (offerInstance) { + offerInstance.reason = params.reason + offerInstance.save() + redirect(action: "list") + } + /* Else we return a flash message */ + else { + flash.message = "offer.not.found" + flash.args = [params.id] + flash.defaultMessage = "Offer not found with id ${params.id}" + redirect(action: "list") + } + } + def dataTableDataAsJSON = { def list = [] def ret = [] def status = new HashSet() response.setHeader("Cache-Control", "no-store") + /* If the user is the admin or a formation manager, status we want to display currents offers */ if(authenticateService.ifAnyGranted("ROLE_ADMIN,ROLE_FORMATIONMANAGER")) { Promotion.getCurrents().offers.each() { it.each() { it2 -> @@ -188,16 +306,27 @@ class OfferController { } list = status } + /* If the user is a staff's member we get all currents offers which were created by the current user and all currents offers which are validated*/ else if(authenticateService.ifAnyGranted("ROLE_STAFF")) { + def userInstance = authenticateService.userDomain() + sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) Promotion.getCurrents().offers.each() { it.each() { it2 -> - if(it2.getStatus() == params.status) { + if(it2.author == userInstance && it2.getStatus() == params.status) { + status.add it2 + } + } + } + Promotion.getCurrents().offers.each() { + it.each() { it2 -> + if(it2.getStatus() == 'offer.validated' && it2.getStatus() == params.status) { status.add it2 } } } list = status } + /* If the user is a student he will only see currents validated offers */ else if(authenticateService.ifAnyGranted("ROLE_STUDENT")) { def userInstance = authenticateService.userDomain() sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) @@ -211,6 +340,7 @@ class OfferController { } } } + /* If the user is an external he will only see currents offers he had created */ else if(authenticateService.ifAnyGranted("ROLE_EXTERNAL")) { def userInstance = authenticateService.userDomain() sessionFactory.currentSession.refresh(userInstance, LockMode.NONE) @@ -232,14 +362,13 @@ class OfferController { company:it.company.toString(), beginAt:it.beginAt?.formatDate(), length:it.length, - //status:it.validated==false?(it.reason==null?message(code:'offer.waitForValidation'):message(code:'offer.unvalidated')):(it.assignated==false?message(code:'offer.validated'):message(code:'offer.assignated')), status:message(code:it.getStatus()), urlID: it.id ] } def data = [ - totalRecords: Offer.count(), + totalRecords: list.size(), results: ret ] diff --git a/grails-app/domain/me/hcl/seekin/Formation/Promotion.groovy b/grails-app/domain/me/hcl/seekin/Formation/Promotion.groovy index f33c018..1556ac5 100644 --- a/grails-app/domain/me/hcl/seekin/Formation/Promotion.groovy +++ b/grails-app/domain/me/hcl/seekin/Formation/Promotion.groovy @@ -21,4 +21,8 @@ class Promotion { static getCurrents = { Promotion.findAllByMillesime(Millesime.getCurrent()) } + + String toString() { + formation.label + " " + millesime + } } diff --git a/grails-app/domain/me/hcl/seekin/Internship/Internship.groovy b/grails-app/domain/me/hcl/seekin/Internship/Internship.groovy index e4299ec..f16eaaa 100644 --- a/grails-app/domain/me/hcl/seekin/Internship/Internship.groovy +++ b/grails-app/domain/me/hcl/seekin/Internship/Internship.groovy @@ -14,8 +14,13 @@ class Internship { company(component:true) } + static transients = ['status'] + /** Subject of the Internship */ String subject + + /** Description of the Internship */ + String description /** Beginning of the Internship */ Date beginAt @@ -49,6 +54,9 @@ class Internship { /** Millesime of the internship */ Millesime millesime + + /** Reason of the deny */ + String reason /** Constraints used to check if an instance is correct */ static constraints = { @@ -63,9 +71,15 @@ class Internship { convocation(nullable: true) length(nullable: false) millesime(nullable: false) + reason(nullable:true) + description(nullable:true) } String toString() { subject } + + String getStatus(Staff member) { + isApproval==false?(reason==null?'internship.waitForValidation':'internship.unvalidated'):(member==academicTutor?'internship.mine':'internship.validated') + } } diff --git a/grails-app/i18n/messages_en.properties b/grails-app/i18n/messages_en.properties index cd63cff..3da0c39 100644 --- a/grails-app/i18n/messages_en.properties +++ b/grails-app/i18n/messages_en.properties @@ -58,7 +58,9 @@ create=Create edit=Edit update=Update delete=Delete +deny=Deny delete.confirm=Are you sure? +deny.confirm=Explain the reason of deny list=Back to list new=New diff --git a/grails-app/views/internship/create.gsp b/grails-app/views/internship/create.gsp index a1870c7..3b5fa34 100644 --- a/grails-app/views/internship/create.gsp +++ b/grails-app/views/internship/create.gsp @@ -32,32 +32,20 @@

- - - -

- -

- - - -

- -

- - + +

- - + +

- - + +

@@ -78,23 +66,45 @@

- +

- +

- +

+ + +

+ + + +

+ +

+ + + +

+ +

+ + + +

+ +
+
diff --git a/grails-app/views/internship/edit.gsp b/grails-app/views/internship/edit.gsp index 027044a..2f654c2 100644 --- a/grails-app/views/internship/edit.gsp +++ b/grails-app/views/internship/edit.gsp @@ -25,6 +25,13 @@

+ +

+ + + + +

@@ -106,12 +113,16 @@

-

+ - - +

-

+ + + +

+ +
diff --git a/grails-app/views/internship/list.gsp b/grails-app/views/internship/list.gsp index ec5f405..07831b7 100644 --- a/grails-app/views/internship/list.gsp +++ b/grails-app/views/internship/list.gsp @@ -5,7 +5,7 @@ <g:message code="internship.list" /> - + @@ -28,35 +28,114 @@ - - + + + + + + +

+ + + + + + + + + + + + + + +
+
+
diff --git a/grails-app/views/internship/show.gsp b/grails-app/views/internship/show.gsp index 7af773b..c0ce656 100644 --- a/grails-app/views/internship/show.gsp +++ b/grails-app/views/internship/show.gsp @@ -33,6 +33,15 @@

+ +

+ + + + ${fieldValue(bean: internshipInstance, field: "description")} + + +

diff --git a/grails-app/views/offer/create.gsp b/grails-app/views/offer/create.gsp index 13cdd89..1e202b6 100644 --- a/grails-app/views/offer/create.gsp +++ b/grails-app/views/offer/create.gsp @@ -49,12 +49,6 @@

- -

- - - -

@@ -70,7 +64,16 @@ />
- + +

+ + +

+
diff --git a/grails-app/views/offer/edit.gsp b/grails-app/views/offer/edit.gsp index b3d035e..fc9817f 100644 --- a/grails-app/views/offer/edit.gsp +++ b/grails-app/views/offer/edit.gsp @@ -18,6 +18,7 @@ +

@@ -53,23 +54,38 @@

- +

+ + +

- - + -

- -

+

- - + + -

+

+ +
- + + + + + + + + + +
diff --git a/grails-app/views/offer/list.gsp b/grails-app/views/offer/list.gsp index a47b887..73325fb 100644 --- a/grails-app/views/offer/list.gsp +++ b/grails-app/views/offer/list.gsp @@ -15,7 +15,9 @@
+ + diff --git a/grails-app/views/offer/show.gsp b/grails-app/views/offer/show.gsp index 49c2cf3..9da33bd 100644 --- a/grails-app/views/offer/show.gsp +++ b/grails-app/views/offer/show.gsp @@ -47,7 +47,7 @@ - ${offerInstance?.beginAt} + ${offerInstance?.beginAt?.formatDate()}

@@ -60,24 +60,6 @@

- -

- - - - - - -

- -

- - - - - - -

@@ -130,7 +112,12 @@

- + + + + + +