de.fau.amos4.web.EmployeeFormController.java Source code

Java tutorial

Introduction

Here is the source code for de.fau.amos4.web.EmployeeFormController.java

Source

/**
 * Personalfragebogen 2.0. Revolutionize form data entry for taxation and
 * other purposes.
 * Copyright (C) 2015 Attila Bujaki, Werner Sembach, Jonas Grger, Oswaldo
 *     Bejarano, Ardhi Sutadi, Nikitha Mohan, Benedikt Rauh
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package de.fau.amos4.web;

import java.io.IOException;
import java.security.Principal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import de.fau.amos4.configuration.AppContext;
import de.fau.amos4.model.Client;
import de.fau.amos4.model.Employee;
import de.fau.amos4.model.fields.Denomination;
import de.fau.amos4.model.fields.HealthInsurance;
import de.fau.amos4.model.fields.MaritalStatus;
import de.fau.amos4.model.fields.NursingCareInsurance;
import de.fau.amos4.model.fields.Parenthood;
import de.fau.amos4.model.fields.PensionInsurance;
import de.fau.amos4.model.fields.Sex;
import de.fau.amos4.model.fields.TypeOfFixedTermContract;
import de.fau.amos4.model.fields.UnemploymentInsurance;
import de.fau.amos4.model.fields.YesNo;
import de.fau.amos4.service.ClientRepository;
import de.fau.amos4.service.ClientService;
import de.fau.amos4.service.EmployeeRepository;
import de.fau.amos4.service.EmployeeService;
import de.fau.amos4.util.CheckDataInput;
import de.fau.amos4.util.FormGenerator;
import de.fau.amos4.util.TokenGenerator;

@Controller
public class EmployeeFormController {
    private final EmployeeRepository employeeRepository;
    private final ClientRepository clientRepository;
    private final ClientService clientService;
    private final EmployeeService employeeService;

    /*
    Constructor called at program start.
     */
    @Autowired
    public EmployeeFormController(EmployeeRepository employeeRepository, ClientRepository clientRepository,
            ClientService clientService, EmployeeService employeeService) {
        this.clientService = clientService;
        this.employeeRepository = employeeRepository;
        this.clientRepository = clientRepository;
        this.employeeService = employeeService;
    }

    /*
    EmployeeEdit handles employee/edit.html
    It is invoked by the edit button in the client/dashboard.html
    The client can edit the prefilled fields of one respective employee entry in the dashboard.
     */
    @RequestMapping("/employee/edit")
    public ModelAndView EmployeeEdit(HttpServletResponse response, @RequestParam(value = "id") long employeeId,
            Principal principal, Model model) throws IOException {
        ModelAndView mav = new ModelAndView();
        mav.setViewName("employee/edit");
        Employee employee = employeeRepository.findOne(employeeId);
        FormGenerator generator = new FormGenerator();
        mav.addObject("formInfo", generator.Generate(Employee.class, employee));
        mav.addObject("id", employeeId);
        mav.addObject("employee", employee);
        // TODO: Move these 'enum' fields to a method with @ModelAttribute so that its available in the whole controller
        // TODO: Consider if it makes sense to add that as an advice so that its available to all controllers application-wide
        mav.addObject("allDisabled", YesNo.values());
        mav.addObject("allMarital", MaritalStatus.values());
        mav.addObject("allSex", Sex.values());
        mav.addObject("allDenomination", Denomination.values());
        mav.addObject("allTypeOfContract", TypeOfFixedTermContract.values());
        mav.addObject("allHealthInsurance", HealthInsurance.values());
        mav.addObject("allNursingCareInsurance", NursingCareInsurance.values());
        mav.addObject("allPensionInsurance", PensionInsurance.values());
        mav.addObject("allParenthood", Parenthood.values());
        mav.addObject("addUnemploymentInsurance", UnemploymentInsurance.values());
        return mav;
    }

    /*
    EmployeeEditSubmit is invoked by the submit button in the employee/edit.html page.
    Changes made there are stored in the database and the client gets redirected to client/dashboard.html.
     */
    @RequestMapping("/employee/edit/submit")
    public ModelAndView EmployeeEditSubmit(@ModelAttribute Employee employee, Principal principal) {
        ModelAndView mav = new ModelAndView();
        FormGenerator generator = new FormGenerator();
        mav.addObject("formInfo", generator.Generate(Employee.class, employee));

        CheckDataInput cdi = new CheckDataInput();

        // Fields with ValidFormat annotation and no content.
        List<String> emptyFields = cdi.listEmptyFields(employee);

        // Fields with ValidFormat annotation and not valid content based on the annotation regex.
        List<String> invalidFields = cdi.listInvalidFields(employee);

        // List of invalid and not empty fields
        List<String> invalidNonEmptyFields = new ArrayList<String>();
        invalidNonEmptyFields.addAll(invalidFields);
        invalidNonEmptyFields.removeAll(emptyFields);

        // If there is a not empty, invalid field, can't accept input.
        if (invalidNonEmptyFields.size() > 0) {
            mav.addObject("invalidFieldErrorMessages", invalidNonEmptyFields);
            mav.setViewName("employee/edit");
            mav.addObject("preview", false);
            return mav; // Display "/employee/edit" with error messages
        } else {
            // There is no invalid and non empty field. -> Accept input.
            // Display warnings because of empty fields:
            mav.addObject("emptyFields", emptyFields);

            if (principal == null) {
                mav.addObject("allDisabled", YesNo.values());
                mav.addObject("allMarital", MaritalStatus.values());
                mav.addObject("allSex", Sex.values());
                mav.addObject("allDenomination", Denomination.values());
                mav.addObject("allTypeOfContract", TypeOfFixedTermContract.values());
                mav.addObject("allHealthInsurance", HealthInsurance.values());
                mav.addObject("allNursingCareInsurance", NursingCareInsurance.values());
                mav.addObject("allPensionInsurance", PensionInsurance.values());
                mav.addObject("addUnemploymentInsurance", UnemploymentInsurance.values());
                mav.addObject("allParenthood", Parenthood.values());
                ;
                mav.addObject("preview", true);
                mav.setViewName("employee/edit");
                return mav;
            } else {
                final String currentUser = principal.getName();
                System.out.println("not null");
                Client client = clientService.getClientByEmail(currentUser);
                employee.setClient(client);
                client.getEmployees().add(employee);

                employeeRepository.save(employee);
                clientRepository.save(client);
                mav.setViewName("redirect:/client/dashboard");
                // Redirect to AccountPage page
                return mav;
            }
        }
    }

    /*
    EmployeeTokenSubmit is invoked on click of the submit botton on employee/token.html
    If the token is valid, the employee gets redirected to the prefilled employee/form.html to make changes on
    the data associated with the token.
        
    If the token is invalid, an error message shows up on the screen.
        
    After a token is used, it becomes invalid.
     */
    @RequestMapping("/employee/token/submit")
    public ModelAndView EmployeeTokenSubmit(HttpServletResponse response,
            @RequestParam(value = "token", required = true) String token, Model model) throws IOException {
        long employeeId = 0;
        Iterable<Employee> allEmployees = employeeRepository.findAll();
        for (Iterator<Employee> i = allEmployees.iterator(); i.hasNext();) {
            Employee currEmployee = i.next();
            if (currEmployee.getToken().equals(token)) {
                employeeId = currEmployee.getId();
            }
        }

        ModelAndView mav = new ModelAndView();
        if (employeeId != 0) {
            mav.setViewName("employee/edit");
            Employee employee = employeeRepository.findOne(employeeId);
            FormGenerator generator = new FormGenerator();
            mav.addObject("formInfo", generator.Generate(Employee.class, employee));
            mav.addObject("id", employeeId);
            mav.addObject("employee", employee);
            mav.addObject("allDisabled", YesNo.values());
            mav.addObject("allMarital", MaritalStatus.values());
            mav.addObject("allSex", Sex.values());
            mav.addObject("allDenomination", Denomination.values());
            mav.addObject("allTypeOfContract", TypeOfFixedTermContract.values());
            mav.addObject("allHealthInsurance", HealthInsurance.values());
            mav.addObject("allNursingCareInsurance", NursingCareInsurance.values());
            mav.addObject("allPensionInsurance", PensionInsurance.values());
            mav.addObject("addUnemploymentInsurance", UnemploymentInsurance.values());
            mav.addObject("allParenthood", Parenthood.values());
        } else {
            mav.addObject("m", "invalid");
            mav.setViewName("employee/token");
        }
        return mav;
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("dd/MM/yyyy"), true, 10));
    }

    /*
    EmployeeConfirm handles employee/confirm.html
    Invoked by: Submit button in employee/preview.html
        
    Apart from providing the opportunity to download the data as text file or pdf, the
    previously entered data is stored in the database.
     */
    @RequestMapping("/employee/confirm")
    public String EmployeeConfirm(@ModelAttribute("employee") Employee employee, BindingResult result, Model model)
            throws Exception {
        Employee e = employeeService.getEmployeeByToken(employee.getToken());
        try {
            Client client = e.getClient();
            if (client != null) {
                employee.setClient(client);
                client.getEmployees().add(employee);
                clientRepository.save(client);
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }

        String token = TokenGenerator.getInstance().createUniqueToken(employeeRepository);
        employee.setToken(token);

        // If the employee is new: Create
        // If the employee already has a primary key: Update
        employeeRepository.save(employee);

        // Setup model and return view
        model.addAttribute("EmployeeId", employee.getId());
        return "employee/confirm";
    }

    // Exception handling - Display exception information
    @ExceptionHandler(Exception.class)
    public ModelAndView handleError(HttpServletRequest req, Exception exception) {
        // TODO: Add logging!
        ModelAndView mav = new ModelAndView();
        mav.addObject("url", req.getRequestURL());
        mav.addObject("message", exception.getMessage());
        // TODO: Implement stacktrace display function.

        return mav;
    }

    /*
    Invoked by: Delete button on client/dashboard.html
        
    The respective employee is deleted in the database, recovery is not possible
     */
    @RequestMapping("/employee/delete")
    public String EmployeeDelete(@RequestParam(value = "id", required = true) long employeeId) {
        //TODO: Security, allow deletion only for employees assigned to respective client.
        // Remove employee with passed id
        this.employeeRepository.delete(employeeId);

        // Redirect to AccountPage page
        return "redirect:/client/dashboard";
    }

    /*
    Invoked by: New Employee link on client/dashboard.html
        
    Creates a new employee in the database.
     */
    @RequestMapping("/employee/new")
    public String EmployeeNew(Principal principal) {
        // Create a new employee with default name
        Employee employee = new Employee();

        final String currentUser = principal.getName();
        Client client = clientService.getClientByEmail(currentUser);

        Locale locale = LocaleContextHolder.getLocale();
        String newEmployee = AppContext.getApplicationContext().getMessage("EmployeeFormController.newEmployee",
                null, locale);
        employee.setFamilyName(newEmployee);
        employee.setClient(client);
        String token = TokenGenerator.getInstance().createUniqueToken(employeeRepository);
        employee.setToken(token);
        client.getEmployees().add(employee);

        employeeRepository.save(employee);
        clientRepository.save(client);

        // Redirect to AccountPage page
        return "redirect:/client/dashboard";
    }

    @RequestMapping({ "/employee/token", "/FrontPage" }) //FrontPage mapping is required by user story TODO ask PO's about this?
    public String EmployeeToken(Model model) throws Exception {
        return "employee/token";
    }
}