Java tutorial
/* * The MIT License * * Copyright 2013 RBC1B. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package uk.org.rbc1b.roms.controller.volunteer; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.util.FileCopyUtils; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.util.UriComponentsBuilder; import uk.org.rbc1b.roms.controller.ResourceNotFoundException; import uk.org.rbc1b.roms.controller.admin.users.UserModelFactory; import uk.org.rbc1b.roms.controller.common.DataConverterUtil; import uk.org.rbc1b.roms.controller.common.PhoneNumberFormatter; import uk.org.rbc1b.roms.controller.common.datatable.AjaxDataTableResult; import uk.org.rbc1b.roms.controller.common.model.PersonModelFactory; import uk.org.rbc1b.roms.controller.qualification.QualificationModel; import uk.org.rbc1b.roms.db.Address; import uk.org.rbc1b.roms.db.Congregation; import uk.org.rbc1b.roms.db.CongregationDao; import uk.org.rbc1b.roms.db.Person; import uk.org.rbc1b.roms.db.PersonDao; import uk.org.rbc1b.roms.db.application.User; import uk.org.rbc1b.roms.db.application.UserDao; import uk.org.rbc1b.roms.db.reference.ReferenceDao; import uk.org.rbc1b.roms.db.volunteer.Volunteer; import uk.org.rbc1b.roms.db.volunteer.VolunteerDao; import uk.org.rbc1b.roms.db.volunteer.VolunteerDao.VolunteerData; import uk.org.rbc1b.roms.db.volunteer.VolunteerSearchCriteria; import uk.org.rbc1b.roms.db.volunteer.department.Assignment; import uk.org.rbc1b.roms.db.volunteer.department.AssignmentRole; import uk.org.rbc1b.roms.db.volunteer.department.Department; import uk.org.rbc1b.roms.db.volunteer.department.DepartmentDao; import uk.org.rbc1b.roms.db.volunteer.department.Team; import uk.org.rbc1b.roms.db.volunteer.interview.InterviewSession; import uk.org.rbc1b.roms.db.volunteer.interview.InterviewSessionDao; import uk.org.rbc1b.roms.db.volunteer.interview.VolunteerInterviewSession; import uk.org.rbc1b.roms.db.volunteer.qualification.Qualification; import uk.org.rbc1b.roms.db.volunteer.qualification.QualificationDao; import uk.org.rbc1b.roms.db.volunteer.qualification.VolunteerQualification; import uk.org.rbc1b.roms.db.volunteer.skill.Skill; import uk.org.rbc1b.roms.db.volunteer.skill.SkillDao; import uk.org.rbc1b.roms.db.volunteer.skill.SkillSearchCriteria; import uk.org.rbc1b.roms.db.volunteer.skill.VolunteerSkill; import uk.org.rbc1b.roms.db.volunteer.trade.VolunteerTrade; import com.google.common.base.Functions; import com.google.common.collect.ImmutableSortedMap; import com.google.common.collect.Ordering; /** * @author rahulsingh */ @Controller @RequestMapping("/volunteers") public class VolunteersController { private static final String MARRIED_MARITAL_STATUS = "MR"; private static final String RBC_STATUS_PENDING = "PD"; private static final String FULLTIME_REGULAR_PIONEER = "RP"; private static final String APPOINTMENT_ELDER = "EL"; private static final String APPOINTMENT_MINISTERIAL_SERVANT = "MS"; private static final String VOLUNTEER_IMAGE_DIRECTORY_KEY = "volunteer.images.directory"; private static final Set<VolunteerData> VOLUNTEER_DATA = EnumSet.of(VolunteerData.SPOUSE, VolunteerData.EMERGENCY_CONTACT, VolunteerData.TRADES, VolunteerData.INTERVIEWER); @Autowired private VolunteerDao volunteerDao; @Autowired private PersonDao personDao; @Autowired private CongregationDao congregationDao; @Autowired private ReferenceDao referenceDao; @Autowired private VolunteerModelFactory volunteerModelFactory; @Autowired private AssignmentModelFactory assignmentModelFactory; @Autowired private VolunteerEmergencyContactModelFactory volunteerEmergencyContactModelFactory; @Autowired private VolunteerBadgePdfModelFactory volunteerBadgePdfModelFactory; @Autowired private InterviewSessionDao interviewSessionDao; @Autowired private DepartmentDao departmentDao; @Autowired private SkillDao skillDao; @Autowired private QualificationDao qualificationDao; @Autowired private UserDao userDao; @Resource(name = "imageDirectories") private Properties imageDirectories; /** * Display a list of volunteers. * * @param model mvc model * @param searchCriteria search criteria * @return view */ @RequestMapping(method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'READ')") public String showVolunteerList(ModelMap model, VolunteerSearchCriteria searchCriteria) { model.addAttribute("volunteers", volunteerDao.findVolunteers(searchCriteria)); model.addAttribute("newUri", VolunteerModelFactory.generateUri(null) + "new"); return "volunteers/list"; } /** * Display the list of volunteers. * * @param requestData data tables request data * @return view */ @RequestMapping(method = RequestMethod.GET, headers = "Accept=application/json") @PreAuthorize("hasPermission('VOLUNTEER', 'READ')") @ResponseBody public AjaxDataTableResult<VolunteerListModel> showDatatableAjaxVolunteerList( VolunteerAjaxDataTableRequestData requestData) { VolunteerSearchCriteria searchCriteria = new VolunteerSearchCriteria(); requestData.populateSearchCriteria(searchCriteria); searchCriteria.setCongregationId(requestData.getCongregationId()); searchCriteria.setDepartmentId(requestData.getDepartmentId()); searchCriteria.setForename(requestData.getForename()); searchCriteria.setId(requestData.getId()); searchCriteria.setKingdomHallId(requestData.getKingdomHallId()); searchCriteria.setLocation(requestData.getLocation()); searchCriteria.setSurname(requestData.getSurname()); searchCriteria.setSkillId(requestData.getSkillId()); searchCriteria.setQualificationId(requestData.getQualificationId()); AjaxDataTableResult<VolunteerListModel> result = new AjaxDataTableResult<VolunteerListModel>(); result.setEcho(requestData.getEcho()); int totalFilteredResults = volunteerDao.findVolunteersCount(searchCriteria); if (searchCriteria.isFiltered()) { VolunteerSearchCriteria noFilterCriteria = searchCriteria.clone(); noFilterCriteria.clearFilter(); result.setTotalRecords(volunteerDao.findVolunteersCount(searchCriteria)); } else { result.setTotalRecords(totalFilteredResults); } if (totalFilteredResults > 0) { List<Volunteer> volunteers = volunteerDao.findVolunteers(searchCriteria); List<VolunteerListModel> modelList = new ArrayList<VolunteerListModel>(volunteers.size()); for (Volunteer volunteer : volunteers) { modelList.add(volunteerModelFactory.generateVolunteerListModel(volunteer)); } result.setRecords(modelList); result.setTotalDisplayRecords(totalFilteredResults); } else { result.setRecords(Collections.<VolunteerListModel>emptyList()); } return result; } /** * @param volunteerId volunteer primary key * @param model model * @return view name * id is found */ @RequestMapping(value = "{volunteerId}", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'READ')") public String showVolunteer(@PathVariable Integer volunteerId, ModelMap model) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { if (personDao.findPerson(volunteerId) != null) { return "redirect:" + PersonModelFactory.generateUri(volunteerId); } throw new ResourceNotFoundException("No volunteer or person with id [" + volunteerId + "]"); } List<Assignment> assignments = volunteerDao.findAssignments(volunteerId); List<VolunteerSkill> skills = volunteerDao.findSkills(volunteerId); List<VolunteerQualification> volunteerQualifications = volunteerDao.findQualifications(volunteerId); model.addAttribute("volunteer", volunteerModelFactory.generateVolunteerModel(volunteer)); model.addAttribute("emergencyContacts", generateEmergencyContacts(volunteer)); model.addAttribute("relationshipValues", referenceDao.findRelationshipValues()); model.addAttribute("assignments", generateAssignments(assignments)); model.addAttribute("volunteerSkills", volunteerModelFactory.generateVolunteerSkillsModel(skills)); model.addAttribute("volunteerQualifications", volunteerModelFactory.generateVolunteerQualificationsModel(volunteerQualifications)); model.addAttribute("trades", volunteerModelFactory.generateVolunteerTradesModel(volunteer.getTrades())); model.addAttribute("interviews", generateInterviewsModel(volunteerId)); if (volunteer.isPhotoProvided() && volunteer.getPerson().getBirthDate() != null && assignments != null) { model.addAttribute("badgeUri", VolunteerBadgePdfModelFactory.generateUri(volunteerId)); } model.addAttribute("rbcStatusCodes", referenceDao.findRBCStatusValues()); model.addAttribute("tradeNumbers", referenceDao.findTradeNumbers()); model.addAttribute("teams", referenceDao.findTeams()); model.addAttribute("assignmentRoles", referenceDao.findAssignmentRoleValues()); model.addAttribute("skills", findSkills()); model.addAttribute("qualifications", findQualifications()); User user = userDao.findUser(volunteerId); if (user != null) { model.addAttribute("userUri", UserModelFactory.generateUri(volunteerId)); } else { model.addAttribute("createUserUri", UserModelFactory.generateUri(null) + "/new?userId=" + volunteerId); } return "volunteers/show"; } /** * Creates a map for qualifications. * * @return reference map for all qualifications */ private Map<Integer, QualificationModel> findQualifications() { List<Qualification> qualifications = qualificationDao.findQualifications(); Map<Integer, QualificationModel> map = new HashMap<Integer, QualificationModel>(); for (Qualification qualification : qualifications) { QualificationModel model = new QualificationModel(); model.setName(qualification.getName()); map.put(qualification.getQualificationId(), model); } return map; } /** * @return reference map for all skills. */ private Map<Integer, DepartmentSkillNameModel> findSkills() { List<Department> departments = departmentDao.findDepartments(); Map<Integer, String> departmentNames = new HashMap<Integer, String>(); for (Department department : departments) { departmentNames.put(department.getDepartmentId(), department.getName()); } List<Skill> skills = skillDao.findSkills(new SkillSearchCriteria()); Map<Integer, DepartmentSkillNameModel> skillNames = new HashMap<Integer, DepartmentSkillNameModel>( skills.size()); for (Skill skill : skills) { String departmentName = departmentNames.get(skill.getDepartment().getDepartmentId()); skillNames.put(skill.getSkillId(), new DepartmentSkillNameModel(departmentName, skill.getName())); } // return the map, sorted by the value (department + skill name) return ImmutableSortedMap.copyOf(skillNames, Ordering.natural().onResultOf(Functions.forMap(skillNames))); } /** * Displays a Volunteers Qualification for editing. * * @param volunteerQualificationId skill ID to edit * @param model mvc model * @return view name */ @RequestMapping(value = "{volunteerId}/qualifications/{volunteerQualificationId}/edit", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String showEditVolunteerQualificationForm(@PathVariable Integer volunteerQualificationId, ModelMap model) { VolunteerQualification volunteerQualification = volunteerDao.findQualification(volunteerQualificationId); if (volunteerQualification == null) { throw new ResourceNotFoundException( "No volunteer qualification #" + volunteerQualificationId + " found"); } Volunteer volunteer = volunteerDao.findVolunteer(volunteerQualification.getPersonId(), EnumSet.noneOf(VolunteerData.class)); VolunteerQualificationForm form = new VolunteerQualificationForm(); form.setComments(volunteerQualification.getComments()); form.setQualificationId(volunteerQualification.getQualificationId()); model.addAttribute("volunteerQualification", form); model.addAttribute("forename", volunteer.getPerson().getForename()); model.addAttribute("surname", volunteer.getPerson().getSurname()); model.addAttribute("qualificationValues", referenceDao.findQualificationValues()); model.addAttribute("submitUri", VolunteerModelFactory.generateUri(volunteerQualification.getVolunteerQualificationId()) + "/qualifications"); return "volunteers/edit-qualification"; } /** * Generate the models for the emergency contacts. At the moment, there is * only one emergency contact an this is part of the volunteer record. * Ultimately, there should be a one to many relationship so there can be * multiple emergency contacts. This function acts as if there might be * many, returning a list, even though there is currently only ever going to * be one. * * @param volunteer volunteer containing the single current emergency * contact * @return model list */ private List<VolunteerEmergencyContactModel> generateEmergencyContacts(Volunteer volunteer) { Person emergencyContact = volunteer.getEmergencyContact(); List<VolunteerEmergencyContactModel> modelList = new ArrayList<VolunteerEmergencyContactModel>( emergencyContact == null ? 0 : 1); if (emergencyContact != null) { modelList.add(volunteerEmergencyContactModelFactory.generateVolunteerEmergencyContactModel(volunteer)); } return modelList; } /** * Generate the models for the volunteer assignments. * * @param assignments assignments * @return model list */ private List<AssignmentModel> generateAssignments(List<Assignment> assignments) { if (CollectionUtils.isEmpty(assignments)) { return null; } List<AssignmentModel> modelList = new ArrayList<AssignmentModel>(assignments.size()); for (Assignment assignment : assignments) { modelList.add(assignmentModelFactory.generateAssignmentModel(assignment)); } return modelList; } private List<VolunteerInterviewModel> generateInterviewsModel(Integer volunteerId) { List<VolunteerInterviewSession> interviews = interviewSessionDao .findVolunteerInterviewSessionsByVolunteer(volunteerId); if (CollectionUtils.isEmpty(interviews)) { return null; } List<VolunteerInterviewModel> modelList = new ArrayList<VolunteerInterviewModel>(); for (VolunteerInterviewSession interview : interviews) { InterviewSession session = interviewSessionDao .findInterviewSession(interview.getInterviewSession().getInterviewSessionId()); modelList.add(volunteerModelFactory.generateVolunteerInterviewModel(interview, session)); } Collections.sort(modelList, new Comparator<VolunteerInterviewModel>() { @Override public int compare(VolunteerInterviewModel model1, VolunteerInterviewModel model2) { return model2.getDate().compareTo(model1.getDate()); } }); return modelList; } /** * Display the form to create a new volunteer. * * @param model mvc model * @return view name */ @RequestMapping(value = "new", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'ADD')") public String showCreateVolunteerForm(ModelMap model) { // initialise the form bean model.addAttribute("volunteer", new VolunteerForm()); model.addAttribute("relationshipValues", referenceDao.findRelationshipValues()); return "volunteers/create"; } /** * Handle the volunteer core details form submission. * <p> * This handles new volunteer creation only. * * @param form volunteer form * @return redirect url */ @RequestMapping(method = RequestMethod.POST) @PreAuthorize("hasPermission('VOLUNTEER', 'ADD')") public String createVolunteer(@Valid VolunteerForm form) { Volunteer volunteer; // look up the existing volunteer/person if possible if (form.getPersonId() != null) { volunteer = volunteerDao.findVolunteer(form.getPersonId(), VOLUNTEER_DATA); if (volunteer == null) { volunteer = new Volunteer(); Person person = personDao.findPerson(form.getPersonId()); if (person != null) { volunteer.setPerson(person); } } } else { volunteer = new Volunteer(); } // save/update the underlying person data Person person = volunteer.getPerson(); Address address = new Address(); address.setStreet(form.getStreet()); address.setTown(form.getTown()); // county is not set in the create volunteer form - it is not on the S-82 paper form address.setPostcode(form.getPostcode()); person.setAddress(address); person.setBirthDate(DataConverterUtil.toSqlDate(form.getBirthDate())); Integer congregationId = person.getCongregation() != null ? person.getCongregation().getCongregationId() : null; if (ObjectUtils.notEqual(congregationId, form.getCongregationId())) { person.setCongregation(congregationDao.findCongregation(form.getCongregationId())); } person.setEmail(form.getEmail()); person.setForename(form.getForename()); person.setMiddleName(form.getMiddleName()); person.setSurname(form.getSurname()); person.setMobile(PhoneNumberFormatter.format(form.getMobile())); person.setTelephone(PhoneNumberFormatter.format(form.getTelephone())); person.setWorkPhone(PhoneNumberFormatter.format(form.getWorkPhone())); // save the volunteer specific data volunteer.setBaptismDate(DataConverterUtil.toSqlDate(form.getBaptismDate())); volunteer.setFormDate(DataConverterUtil.toSqlDate(form.getFormDate())); if (form.isElder()) { volunteer.setAppointmentCode(APPOINTMENT_ELDER); } else if (form.isMinisterialServant()) { volunteer.setAppointmentCode(APPOINTMENT_MINISTERIAL_SERVANT); } volunteer.setGender(form.getGender()); if (form.isRegularPioneer()) { volunteer.setFulltimeCode(FULLTIME_REGULAR_PIONEER); } Person emergencyContact = createEmergencyContact(form); volunteer.setEmergencyContact(emergencyContact); volunteer.setEmergencyContactRelationshipCode(form.getEmergencyRelationshipCode()); Person spouse = createSpouse(form, emergencyContact); if (spouse != null) { volunteer.setMaritalStatusCode(MARRIED_MARITAL_STATUS); volunteer.setSpouse(spouse); } volunteer.setRbcStatusCode(RBC_STATUS_PENDING); if (form.getTrades() != null) { Set<VolunteerTrade> volunteerTrades = new HashSet<VolunteerTrade>(); for (VolunteerTrade trade : form.getTrades()) { if (StringUtils.isNotBlank(trade.getName())) { trade.setVolunteer(volunteer); volunteerTrades.add(trade); } } if (!volunteerTrades.isEmpty()) { volunteer.setTrades(volunteerTrades); } } volunteerDao.createVolunteer(volunteer); return "redirect:" + VolunteerModelFactory.generateUri(volunteer.getPersonId()); } /** * Display the form to edit the info under the spiritual tab on the * volunteer. * * @param volunteerId volunteer id to edit * @param model mvc model * @return view name */ @RequestMapping(value = "{volunteerId}/spiritual/edit", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String showEditVolunteerSpiritualForm(@PathVariable Integer volunteerId, ModelMap model) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, EnumSet.noneOf(VolunteerData.class)); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } VolunteerSpiritualForm form = new VolunteerSpiritualForm(); form.setAppointmentCode(volunteer.getAppointmentCode()); form.setBaptismDate(DataConverterUtil.toDateTime(volunteer.getBaptismDate())); if (volunteer.getPerson().getCongregation() != null) { Congregation congregation = congregationDao .findCongregation(volunteer.getPerson().getCongregation().getCongregationId()); form.setCongregationName(congregation.getName()); form.setCongregationId(congregation.getCongregationId()); } form.setFulltimeCode(volunteer.getFulltimeCode()); model.addAttribute("volunteerSpiritual", form); model.addAttribute("forename", volunteer.getPerson().getForename()); model.addAttribute("surname", volunteer.getPerson().getSurname()); model.addAttribute("fulltimeValues", referenceDao.findFulltimeValues()); model.addAttribute("appointmentValues", referenceDao.findAppointmentValues()); model.addAttribute("submitUri", VolunteerModelFactory.generateUri(volunteerId) + "/spiritual"); return "volunteers/edit-spiritual"; } /** * Display the form to edit the info under the rbc status tab on the * volunteer. * * @param volunteerId volunteer id to edit * @param model mvc model * @return view name */ @RequestMapping(value = "{volunteerId}/rbc-status/edit", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String showEditVolunteerRbcStatusForm(@PathVariable Integer volunteerId, ModelMap model) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, EnumSet.of(VolunteerData.INTERVIEWER)); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } VolunteerRbcStatusForm form = new VolunteerRbcStatusForm(); form.setFormDate(DataConverterUtil.toDateTime(volunteer.getFormDate())); if (volunteer.getInterviewerA() != null) { form.setInterviewerAPersonId(volunteer.getInterviewerA().getPersonId()); form.setInterviewerAUserName(volunteer.getInterviewerA().getUserName()); } if (volunteer.getInterviewerB() != null) { form.setInterviewerBPersonId(volunteer.getInterviewerB().getPersonId()); form.setInterviewerBUserName(volunteer.getInterviewerB().getUserName()); } form.setInterviewComments(volunteer.getInterviewComments()); form.setJoinedDate(DataConverterUtil.toDateTime(volunteer.getJoinedDate())); form.setBadgeIssueDate(DataConverterUtil.toDateTime(volunteer.getBadgeIssueDate())); if (volunteer.getAvailability() != null && volunteer.getAvailability().length() == 7) { char[] availability = volunteer.getAvailability().toCharArray(); form.setAvailabilityMonday(availability[0] == 'T'); form.setAvailabilityTuesday(availability[1] == 'T'); form.setAvailabilityWednesday(availability[2] == 'T'); form.setAvailabilityThursday(availability[3] == 'T'); form.setAvailabilityFriday(availability[4] == 'T'); form.setAvailabilitySaturday(availability[5] == 'T'); form.setAvailabilitySunday(availability[6] == 'T'); } form.setOversight(volunteer.isOversight()); form.setOversightComments(volunteer.getOversightComments()); form.setReliefAbroad(volunteer.isReliefAbroad()); form.setReliefAbroadComments(volunteer.getReliefAbroadComments()); form.setReliefUK(volunteer.isReliefUK()); form.setReliefUKComments(volunteer.getReliefUKComments()); form.setHhcFormCode(volunteer.getHhcFormCode()); model.addAttribute("volunteerRbcStatus", form); model.addAttribute("forename", volunteer.getPerson().getForename()); model.addAttribute("surname", volunteer.getPerson().getSurname()); model.addAttribute("submitUri", VolunteerModelFactory.generateUri(volunteerId) + "/rbc-status"); return "volunteers/edit-rbc-status"; } /** * Display the form to edit the info under the personal tab on the * volunteer. * * @param volunteerId volunteer id to edit * @param model mvc model * @return view name */ @RequestMapping(value = "{volunteerId}/personal/edit", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String showEditVolunteerPersonalForm(@PathVariable Integer volunteerId, ModelMap model) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, EnumSet.of(VolunteerData.SPOUSE)); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } VolunteerPersonalForm form = new VolunteerPersonalForm(); Person person = volunteer.getPerson(); form.setEmail(person.getEmail()); form.setTelephone(person.getTelephone()); form.setMobile(person.getMobile()); form.setWorkPhone(person.getWorkPhone()); if (person.getAddress() != null) { form.setStreet(person.getAddress().getStreet()); form.setTown(person.getAddress().getTown()); form.setCounty(person.getAddress().getCounty()); form.setPostcode(person.getAddress().getPostcode()); } form.setGender(volunteer.getGender()); if (person.getBirthDate() != null) { form.setBirthDate(new DateTime(person.getBirthDate().getTime())); } form.setMaritalStatusCode(volunteer.getMaritalStatusCode()); if (volunteer.getSpouse() != null) { form.setSpousePersonId(volunteer.getSpouse().getPersonId()); form.setSpouseForename(volunteer.getSpouse().getForename()); form.setSpouseSurname(volunteer.getSpouse().getSurname()); } model.addAttribute("maritalStatusValues", referenceDao.findMaritalStatusValues()); model.addAttribute("volunteerPersonal", form); model.addAttribute("forename", person.getForename()); model.addAttribute("surname", person.getSurname()); model.addAttribute("submitUri", VolunteerModelFactory.generateUri(volunteerId) + "/personal"); return "volunteers/edit-personal"; } /** * Update the volunteer name. * <p> * This is expected to be called with an ajax request, so we return a 204 * response on success * * @param volunteerId volunteer id to edit * @param form form data */ @RequestMapping(value = "{volunteerId}/name", method = RequestMethod.PUT) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerName(@PathVariable Integer volunteerId, @Valid VolunteerNameForm form) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } Person person = volunteer.getPerson(); person.setForename(form.getForename()); person.setMiddleName(form.getMiddleName()); person.setSurname(form.getSurname()); volunteerDao.updateVolunteer(volunteer); } /** * Update the volunteer comments. * <p> * This is expected to be called with an ajax request, so we return a 204 * response on success * * @param volunteerId volunteer id to edit * @param comments comments to set */ @RequestMapping(value = "{volunteerId}/comments", method = RequestMethod.PUT) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerComments(@PathVariable Integer volunteerId, @RequestParam("comments") String comments) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.getPerson().setComments(comments); volunteerDao.updateVolunteer(volunteer); } /** * Update the volunteer spiritual information. * * @param volunteerId volunteer id to edit * @param form form data * @return view name (redirect) */ @RequestMapping(value = "{volunteerId}/spiritual", method = RequestMethod.PUT) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String updateVolunteerSpiritual(@PathVariable Integer volunteerId, @Valid VolunteerSpiritualForm form) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.setBaptismDate(DataConverterUtil.toSqlDate(form.getBaptismDate())); volunteer.setFulltimeCode(form.getFulltimeCode()); volunteer.setAppointmentCode(form.getAppointmentCode()); if (form.getCongregationId() == null) { volunteer.getPerson().setCongregation(null); } else { volunteer.getPerson().setCongregation(congregationDao.findCongregation(form.getCongregationId())); } volunteerDao.updateVolunteer(volunteer); return "redirect:" + VolunteerModelFactory.generateUri(volunteer.getPersonId()) + "#!spiritual"; } /** * Update the volunteer RBC status. * * @param volunteerId volunteer id to edit * @param form form data * @return view name (redirect) */ @RequestMapping(value = "{volunteerId}/rbc-status", method = RequestMethod.PUT) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String updateVolunteerRbcStatus(@PathVariable Integer volunteerId, @Valid VolunteerRbcStatusForm form) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.setFormDate(DataConverterUtil.toSqlDate(form.getFormDate())); if (form.getInterviewerAPersonId() != null) { User user = new User(); user.setPersonId(form.getInterviewerAPersonId()); volunteer.setInterviewerA(user); } else { volunteer.setInterviewerA(null); } if (form.getInterviewerBPersonId() != null) { User user = new User(); user.setPersonId(form.getInterviewerBPersonId()); volunteer.setInterviewerB(user); } else { volunteer.setInterviewerB(null); } volunteer.setInterviewComments(form.getInterviewComments()); volunteer.setJoinedDate(DataConverterUtil.toSqlDate(form.getJoinedDate())); volunteer.setBadgeIssueDate(DataConverterUtil.toSqlDate(form.getBadgeIssueDate())); volunteer.setAvailability(generateAvailability(form.isAvailabilityMonday(), form.isAvailabilityTuesday(), form.isAvailabilityWednesday(), form.isAvailabilityThursday(), form.isAvailabilityFriday(), form.isAvailabilitySaturday(), form.isAvailabilitySunday())); volunteer.setOversight(form.isOversight()); volunteer.setOversightComments(form.getOversightComments()); volunteer.setReliefAbroad(form.isReliefAbroad()); volunteer.setReliefAbroadComments(form.getReliefAbroadComments()); volunteer.setReliefUK(form.isReliefUK()); volunteer.setReliefUKComments(form.getReliefUKComments()); volunteer.setHhcFormCode(form.getHhcFormCode()); volunteerDao.updateVolunteer(volunteer); return "redirect:" + VolunteerModelFactory.generateUri(volunteer.getPersonId()) + "#!rbc-status"; } /** * Update the RBC status code of a volunteer. Not to be confused with the * volunteer's RBC status tab that appears on the volunteer show JSP. This * will be an AJAX request. * * @param volunteerId volunteer id * @param rbcStatusCode RBC status code to be passed in the request * */ @RequestMapping(value = "{volunteerId}/rbc-status-code", method = RequestMethod.PUT) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerRbcStatusCode(@PathVariable Integer volunteerId, @RequestParam("rbcStatusCode") String rbcStatusCode) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.setRbcStatusCode(rbcStatusCode); volunteerDao.updateVolunteer(volunteer); } /** * Update the volunteer personal information. * * @param volunteerId volunteer id to edit * @param form form data * @return view name (redirect) */ @RequestMapping(value = "{volunteerId}/personal", method = RequestMethod.PUT) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String updateVolunteerPersonal(@PathVariable Integer volunteerId, @Valid VolunteerPersonalForm form) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } Person person = volunteer.getPerson(); Address address = new Address(); address.setStreet(form.getStreet()); address.setTown(form.getTown()); address.setCounty(form.getCounty()); address.setPostcode(form.getPostcode()); person.setAddress(address); person.setBirthDate(DataConverterUtil.toSqlDate(form.getBirthDate())); person.setEmail(form.getEmail()); volunteer.setGender(form.getGender()); volunteer.setMaritalStatusCode(form.getMaritalStatusCode()); person.setMobile(PhoneNumberFormatter.format(form.getMobile())); person.setTelephone(PhoneNumberFormatter.format(form.getTelephone())); person.setWorkPhone(PhoneNumberFormatter.format(form.getWorkPhone())); if (form.getSpousePersonId() != null) { volunteer.setSpouse(personDao.findPerson(form.getSpousePersonId())); } else if (form.getSpouseForename() != null && form.getSpouseSurname() != null) { Person spouse = new Person(); spouse.setForename(form.getSpouseForename()); spouse.setSurname(form.getSpouseSurname()); personDao.createPerson(spouse); volunteer.setSpouse(spouse); } else { volunteer.setSpouse(null); } volunteerDao.updateVolunteer(volunteer); return "redirect:" + VolunteerModelFactory.generateUri(volunteer.getPersonId()) + "#!personal"; } /** * Produce the Volunteer Badge PDF. * * @param volunteerId volunteer id of for his/her badge * @param volunteerBadgeId volunteer badge id * * @throws IOException if image file not found * @return modelAndView of the VolunteerBadgePdfView */ @RequestMapping(value = "{volunteerId}/rbc-{volunteerBadgeId}-badge.pdf", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'READ')") public ModelAndView produceVolunteerBadgePdf(@PathVariable Integer volunteerId, @PathVariable Integer volunteerBadgeId) throws IOException { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, VOLUNTEER_DATA); if (volunteerId.equals(volunteerBadgeId)) { VolunteerBadgeColour badgeColour = volunteerBadgePdfModelFactory.determineBadgeColour(volunteer); ModelAndView modelAndView = null; switch (badgeColour) { case GREEN: modelAndView = new ModelAndView("greenVolunteerBadgePdfView"); break; case RED: modelAndView = new ModelAndView("redVolunteerBadgePdfView"); break; case ORANGE: modelAndView = new ModelAndView("orangeVolunteerBadgePdfView"); break; default: modelAndView = new ModelAndView("greyVolunteerBadgePdfView"); break; } String assignment = volunteerBadgePdfModelFactory.generatePrimaryAssignment(volunteer); modelAndView.getModelMap().addAttribute("volunteer", volunteer); modelAndView.getModelMap().addAttribute("assignment", assignment); String imageName = volunteerId + ".jpg"; File imageFile = new File(imageDirectories.getProperty(VOLUNTEER_IMAGE_DIRECTORY_KEY) + imageName); byte[] bytes = FileUtils.readFileToByteArray(imageFile); InputStream inputStream = new ByteArrayInputStream(bytes); BufferedImage bufferedImage = ImageIO.read(inputStream); modelAndView.getModelMap().addAttribute("bufferedImage", bufferedImage); return modelAndView; } else { return new ModelAndView("redirect:" + VolunteerBadgePdfModelFactory.generateUri(volunteerId)); } } /** * Get volunteer image. * <p>This assumes we have already checked the volunteer object to ensure it * exists and that it expects to have an image defined. * * @param volunteerId id * @param response HttpServletResponse * @throws IOException if the file cannot be read * found */ @RequestMapping(value = "{volunteerId}/image", method = RequestMethod.GET) @PreAuthorize("hasPermission('VOLUNTEER', 'READ')") public void showImage(@PathVariable Integer volunteerId, HttpServletResponse response) throws IOException { String imageName = volunteerId + ".jpg"; File file = new File(imageDirectories.getProperty(VOLUNTEER_IMAGE_DIRECTORY_KEY) + imageName); if (!file.exists()) { throw new ResourceNotFoundException("Volunteer #" + volunteerId + " does not have an image defined"); } OutputStream out = response.getOutputStream(); response.setHeader("Content-Disposition", "attachment; filename=\"" + imageName + "\""); response.setContentType("image/jpeg"); BufferedInputStream in = new BufferedInputStream(new FileInputStream(file)); FileCopyUtils.copy(in, out); out.flush(); } /** * Handles the volunteer image upload. * * @param volunteerId id * @param imageFile file to be uploaded * @throws IOException if file cannot be written * @return view * volunteer */ @RequestMapping(value = "{volunteerId}/image", method = RequestMethod.POST) @PreAuthorize("hasPermission('VOLUNTEER', 'EDIT')") public String handleImageUpload(@PathVariable Integer volunteerId, @RequestParam(value = "image", required = true) MultipartFile imageFile) throws IOException { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, EnumSet.of(VolunteerData.INTERVIEWER)); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } String filename = volunteerId + ".jpg"; File file = new File(imageDirectories.getProperty(VOLUNTEER_IMAGE_DIRECTORY_KEY) + filename); FileUtils.writeByteArrayToFile(file, imageFile.getBytes()); volunteer.setPhotoProvided(true); volunteerDao.updateVolunteer(volunteer); return "redirect:" + VolunteerModelFactory.generateUri(volunteerId); } private String generateAvailability(boolean... availabilityDays) { StringBuilder builder = new StringBuilder(7); for (boolean availabilityDay : availabilityDays) { builder.append(availabilityDay ? 'T' : 'F'); } return builder.toString(); } private Person createEmergencyContact(VolunteerForm form) { if (form.getEmergencyContactPersonId() != null) { // NOTE: an existing person which is linked as emergency contact may // have fields which are set to null. return personDao.findPerson(form.getEmergencyContactPersonId()); } Person emergencyContact = new Person(); Address address = new Address(); address.setStreet(form.getEmergencyContactStreet()); address.setTown(form.getEmergencyContactTown()); // county is not set when creating a new contact in the create form address.setPostcode(form.getEmergencyContactPostcode()); emergencyContact.setAddress(address); emergencyContact.setForename(form.getEmergencyContactForename()); emergencyContact.setSurname(form.getEmergencyContactSurname()); emergencyContact.setTelephone(PhoneNumberFormatter.format(form.getEmergencyContactTelephone())); emergencyContact.setMobile(PhoneNumberFormatter.format(form.getEmergencyContactMobile())); return emergencyContact; } private Person createSpouse(VolunteerForm form, Person emergencyContact) { if (form.getSpousePersonId() != null) { return personDao.findPerson(form.getSpousePersonId()); } // if the emergency contact is also new, see if it is the same person if (form.getEmergencyContactPersonId() == null) { if (ObjectUtils.equals(emergencyContact.getForename(), form.getSpouseForename()) && ObjectUtils.equals(emergencyContact.getSurname(), form.getSurname()) && (ObjectUtils.equals(form.getEmergencyRelationshipCode(), "HB") || ObjectUtils.equals(form.getEmergencyRelationshipCode(), "WF"))) { return emergencyContact; } } // if unpopulated, return null if (form.getSpouseForename() == null || form.getSpouseSurname() == null) { return null; } // create a new person Person spouse = new Person(); spouse.setForename(form.getSpouseForename()); spouse.setSurname(form.getSpouseSurname()); return spouse; } /** * Created a department assignment linked to a volunteer. * * @param volunteerId volunteer id * @param form assignment information * @param builder uri builder, for building the response header * @return created status, with the assignment url * assignment is not found */ @RequestMapping(value = "{volunteerId}/assignments", method = RequestMethod.POST) @ResponseStatus(HttpStatus.NO_CONTENT) public ResponseEntity<Void> createVolunteerAssignment(@PathVariable Integer volunteerId, @Valid VolunteerAssignmentForm form, UriComponentsBuilder builder) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } Assignment volunteerAssignment = new Assignment(); volunteerAssignment.setAssignedDate(DataConverterUtil.toSqlDate(form.getAssignedDate())); volunteerAssignment.setDepartmentId(form.getDepartmentId()); volunteerAssignment.setPerson(volunteer.getPerson()); AssignmentRole role = new AssignmentRole(); role.setAssignmentRoleCode(form.getAssignmentRoleCode()); volunteerAssignment.setRole(role); Team team = new Team(); team.setTeamId(form.getTeamId()); volunteerAssignment.setTeam(team); volunteerAssignment.setTradeNumberId(form.getTradeNumberId()); departmentDao.createAssignment(volunteerAssignment); HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/volunteers/{volunteerId}/assignments/{assignmentId}") .buildAndExpand(volunteerId, volunteerAssignment.getAssignmentId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } /** * Delete a department assignment linked to a volunteer. * * @param volunteerId volunteer id * @param assignmentId linked volunteer department assignment id * assignment is not found */ @RequestMapping(value = "{volunteerId}/assignments/{assignmentId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteVolunteerAssignment(@PathVariable Integer volunteerId, @PathVariable Integer assignmentId) { Assignment volunteerAssignment = findAssignment(volunteerId, assignmentId); departmentDao.deleteAssignment(volunteerAssignment); } /** * Update a department assignment linked to a volunteer. * * @param volunteerId volunteer id * @param assignmentId linked volunteer department assignment id * @param form updated data * assignment is not found */ @RequestMapping(value = "{volunteerId}/assignments/{assignmentId}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerAssignment(@PathVariable Integer volunteerId, @PathVariable Integer assignmentId, @Valid VolunteerAssignmentForm form) { Assignment volunteerAssignment = findAssignment(volunteerId, assignmentId); // we don't change the person or the department volunteerAssignment.setAssignedDate(DataConverterUtil.toSqlDate(form.getAssignedDate())); AssignmentRole role = new AssignmentRole(); role.setAssignmentRoleCode(form.getAssignmentRoleCode()); volunteerAssignment.setRole(role); Team team = new Team(); team.setTeamId(form.getTeamId()); volunteerAssignment.setTeam(team); volunteerAssignment.setTradeNumberId(form.getTradeNumberId()); departmentDao.updateAssignment(volunteerAssignment); } private Assignment findAssignment(Integer volunteerId, Integer assignmentId) { List<Assignment> assignments = volunteerDao.findAssignments(volunteerId); Assignment volunteerAssignment = null; if (assignments != null) { for (Assignment assignment : assignments) { if (assignment.getAssignmentId().equals(assignmentId)) { volunteerAssignment = assignment; } } } if (volunteerAssignment == null) { throw new ResourceNotFoundException( "Volunteer #" + volunteerId + " is not linked to assignment #" + assignmentId); } return volunteerAssignment; } /** * Created an emergency contact to a volunteer. * * @param volunteerId volunteer id * @param form emergency contact information * @param builder uri builder, for building the response header * @return created status, with the emergency contact url */ @RequestMapping(value = "{volunteerId}/emergencycontacts", method = RequestMethod.POST) @ResponseStatus(HttpStatus.NO_CONTENT) public ResponseEntity<Void> createVolunteerEmergencyContact(@PathVariable Integer volunteerId, @Valid VolunteerEmergencyContactForm form, UriComponentsBuilder builder) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.setEmergencyContactRelationshipCode(form.getRelationshipCode()); Person emergencyContact; int emergencyContactId = form.getEmergencyContactId(); if (emergencyContactId == -1) { // create a new Person emergencyContact = new Person(); emergencyContact.setForename(form.getFirstName()); emergencyContact.setSurname(form.getSurName()); emergencyContact.setTelephone(PhoneNumberFormatter.format(form.getHomePhone())); emergencyContact.setMobile(PhoneNumberFormatter.format(form.getMobilePhone())); emergencyContact.setWorkPhone(PhoneNumberFormatter.format(form.getWorkPhone())); personDao.createPerson(emergencyContact); } else { emergencyContact = personDao.findPerson(emergencyContactId); } volunteer.setEmergencyContact(emergencyContact); volunteerDao.updateVolunteer(volunteer); HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/volunteers/{volunteerId}/emergencycontacts/{emergencyContactId}") .buildAndExpand(volunteerId, 1).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } /** * Delete an emergency contact linked to a volunteer. * * @param volunteerId volunteer id * @param emergencyContactId linked volunteer emergency contact id * found */ @RequestMapping(value = "{volunteerId}/emergencycontacts/{emergencyContactId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteVolunteerEmergencyContact(@PathVariable Integer volunteerId, @PathVariable Integer emergencyContactId) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.setEmergencyContact(null); volunteer.setEmergencyContactRelationshipCode(null); volunteerDao.updateVolunteer(volunteer); } /** * Update an emergency contact linked to a volunteer. * * @param volunteerId volunteer id * @param emergencyContactId linked volunteer emergency contact id * @param form updated data * found */ @RequestMapping(value = "{volunteerId}/emergencycontacts/{emergencyContactId}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerEmergencyContact(@PathVariable Integer volunteerId, @PathVariable Integer emergencyContactId, @Valid VolunteerEmergencyContactForm form) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteer.setEmergencyContactRelationshipCode(form.getRelationshipCode()); volunteerDao.updateVolunteer(volunteer); } /** * Created a department skill linked to a volunteer. * * @param volunteerId volunteer id * @param form skill information * @param builder uri builder, for building the response header * @return created status, with the skill url * assignment is not found */ @RequestMapping(value = "{volunteerId}/skills", method = RequestMethod.POST) @ResponseStatus(HttpStatus.NO_CONTENT) public ResponseEntity<Void> createVolunteerSkill(@PathVariable Integer volunteerId, @Valid VolunteerSkillForm form, UriComponentsBuilder builder) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } VolunteerSkill volunteerSkill = new VolunteerSkill(); volunteerSkill.setComments(form.getComments()); volunteerSkill.setLevel(form.getLevel()); volunteerSkill.setPersonId(volunteerId); volunteerSkill.setSkillId(form.getSkillId()); volunteerSkill.setTrainingDate(DataConverterUtil.toSqlDate(form.getTrainingDate())); volunteerSkill.setTrainingResults(form.getTrainingResults()); volunteerDao.createSkill(volunteerSkill); HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/volunteers/{volunteerId}/skills/{skillId}") .buildAndExpand(volunteerId, volunteerSkill.getVolunteerSkillId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } /** * Delete a department assignment linked to a volunteer. * * @param volunteerId volunteer id * @param volunteerSkillId linked volunteer skill id * skill is not found */ @RequestMapping(value = "{volunteerId}/skills/{volunteerSkillId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteVolunteerSkill(@PathVariable Integer volunteerId, @PathVariable Integer volunteerSkillId) { VolunteerSkill volunteerSkill = volunteerDao.findSkill(volunteerSkillId); if (volunteerSkill == null) { throw new ResourceNotFoundException("Volunteer skill #" + volunteerSkillId + " is not found"); } if (!volunteerSkill.getPersonId().equals(volunteerId)) { throw new ResourceNotFoundException( "Volunteer #" + volunteerId + " is not linked to skill #" + volunteerSkillId); } volunteerDao.deleteSkill(volunteerSkill); } /** * Update a department skill linked to a volunteer. * * @param volunteerId volunteer id * @param skillId linked volunteer department skill id * @param form updated data * skill is not found */ @RequestMapping(value = "{volunteerId}/skills/{skillId}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerSkill(@PathVariable Integer volunteerId, @PathVariable Integer skillId, @Valid VolunteerSkillForm form) { VolunteerSkill volunteerSkill = volunteerDao.findSkill(skillId); if (volunteerSkill == null || !volunteerSkill.getPersonId().equals(volunteerId)) { throw new ResourceNotFoundException( "Volunteer #" + volunteerId + " is not linked to skill #" + skillId); } // we don't change the skill or department volunteerSkill.setComments(form.getComments()); volunteerSkill.setLevel(form.getLevel()); volunteerSkill.setTrainingDate(DataConverterUtil.toSqlDate(form.getTrainingDate())); volunteerSkill.setTrainingResults(form.getTrainingResults()); volunteerDao.updateSkill(volunteerSkill); } /** * Deletes volunteer trade/experience. * * @param volunteerId the volunteer id * @param volunteerTradeId the volunteer trade id */ @RequestMapping(value = "{volunteerId}/experience/{volunteerTradeId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteVolunteerExperience(@PathVariable Integer volunteerId, @PathVariable Integer volunteerTradeId) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); for (VolunteerTrade trade : volunteer.getTrades()) { if (trade.getVolunteerTradeId() == volunteerTradeId) { volunteerDao.deleteVolunteerTrade(trade); } } } /** * Creates the volunteer experience. * * @param volunteerId the volunteer id * @param form the form data * @param builder the builder * @return response status */ @RequestMapping(value = "{volunteerId}/experience", method = RequestMethod.POST) @ResponseStatus(HttpStatus.NO_CONTENT) public ResponseEntity<Void> createVolunteerExperience(@PathVariable Integer volunteerId, @Valid VolunteerExperienceForm form, UriComponentsBuilder builder) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } VolunteerTrade trade = new VolunteerTrade(); trade.setVolunteer(volunteer); trade.setName(form.getName()); trade.setExperienceDescription(form.getExperienceDescription()); trade.setExperienceYears(Integer.parseInt(form.getExperienceYears())); volunteerDao.createTrade(trade); HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/volunteers/{volunteerId}/experience/{experienceId}") .buildAndExpand(volunteerId, trade.getVolunteerTradeId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } /** * Updates a volunteer experience. * * @param volunteerId the volunteer id * @param volunteerTradeId the volunteer trade id * @param form the valid form data * @param builder the builder */ @RequestMapping(value = "{volunteerId}/experience/{volunteerTradeId}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerExperience(@PathVariable Integer volunteerId, @PathVariable Integer volunteerTradeId, @Valid VolunteerExperienceForm form, UriComponentsBuilder builder) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); VolunteerTrade volunteerTrade = volunteerDao.findTrade(volunteerTradeId); if (volunteer == null || volunteerTrade == null || volunteer.getPersonId() != volunteerTrade.getVolunteer().getPersonId()) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } volunteerTrade.setName(form.getName()); volunteerTrade.setExperienceDescription(form.getExperienceDescription()); volunteerTrade.setExperienceYears(Integer.parseInt(form.getExperienceYears())); volunteerDao.updateTrade(volunteerTrade); } /** * Update the volunteer qualification information. * * @param volunteerId the volunteer id * @param volunteerQualificationId volunteer qualification Id to edit * @param form form data */ @RequestMapping(value = "{volunteerId}/qualifications/{volunteerQualificationId}", method = RequestMethod.PUT) @ResponseStatus(HttpStatus.NO_CONTENT) public void updateVolunteerQualification(@PathVariable Integer volunteerId, @PathVariable Integer volunteerQualificationId, @Valid VolunteerQualificationForm form) { VolunteerQualification volunteerQualification = volunteerDao.findQualification(volunteerQualificationId); if (volunteerQualification == null || volunteerQualification.getPersonId() != volunteerId) { throw new ResourceNotFoundException( "No volunteer qualification #" + volunteerQualificationId + " found"); } volunteerQualification.setComments(form.getComments()); volunteerQualification.setQualificationId(form.getQualificationId()); volunteerDao.updateVolunteerQualification(volunteerQualification); } /** * Delete a qualification linked to a volunteer. * * @param volunteerId volunteer id * @param volunteerQualificationId linked volunteer qualification id * qualification is not found */ @RequestMapping(value = "{volunteerId}/qualifications/{volunteerQualificationId}", method = RequestMethod.DELETE) @ResponseStatus(HttpStatus.NO_CONTENT) public void deleteVolunteerQualification(@PathVariable Integer volunteerId, @PathVariable Integer volunteerQualificationId) { VolunteerQualification volunteerQualification = volunteerDao.findQualification(volunteerQualificationId); if (volunteerQualification == null) { throw new ResourceNotFoundException( "Volunteer qualification #" + volunteerQualificationId + " is not found"); } if (!volunteerQualification.getPersonId().equals(volunteerId)) { throw new ResourceNotFoundException( "Volunteer #" + volunteerId + " is not linked to qualification #" + volunteerQualificationId); } volunteerDao.deleteVolunteerQualification(volunteerQualification); } /** * Created a qualification linked to a volunteer. * * @param volunteerId volunteer id * @param form qualification information * @param builder uri builder, for building the response header * @return created status, with the qualification url * is not found */ @RequestMapping(value = "{volunteerId}/qualifications", method = RequestMethod.POST) @ResponseStatus(HttpStatus.NO_CONTENT) public ResponseEntity<Void> createVolunteerQualification(@PathVariable Integer volunteerId, @Valid VolunteerQualificationForm form, UriComponentsBuilder builder) { Volunteer volunteer = volunteerDao.findVolunteer(volunteerId, null); if (volunteer == null) { throw new ResourceNotFoundException("No volunteer #" + volunteerId + " found"); } VolunteerQualification volunteerQualification = new VolunteerQualification(); volunteerQualification.setComments(form.getComments()); volunteerQualification.setPersonId(volunteerId); volunteerQualification.setQualificationId(form.getQualificationId()); volunteerDao.createQualification(volunteerQualification); HttpHeaders headers = new HttpHeaders(); headers.setLocation(builder.path("/volunteers/{volunteerId}/qualifications/{qualificationId}") .buildAndExpand(volunteerId, volunteerQualification.getVolunteerQualificationId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } }