com.axelor.apps.hr.web.expense.ExpenseController.java Source code

Java tutorial

Introduction

Here is the source code for com.axelor.apps.hr.web.expense.ExpenseController.java

Source

/**
 * Axelor Business Solutions
 *
 * Copyright (C) 2016 Axelor (<http://axelor.com>).
 *
 * This program is free software: you can redistribute it and/or  modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * as published by the Free Software Foundation.
 *
 * 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 com.axelor.apps.hr.web.expense;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.joda.time.LocalDate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.axelor.apps.ReportFactory;
import com.axelor.apps.account.db.Move;
import com.axelor.apps.base.db.Wizard;
import com.axelor.apps.base.service.administration.GeneralService;
import com.axelor.apps.hr.db.Expense;
import com.axelor.apps.hr.db.ExpenseLine;
import com.axelor.apps.base.db.Product;
import com.axelor.apps.hr.db.HRConfig;
import com.axelor.apps.hr.db.KilometricAllowanceRate;
import com.axelor.apps.hr.db.repo.ExpenseRepository;
import com.axelor.apps.hr.db.repo.KilometricAllowanceRateRepository;
import com.axelor.apps.hr.db.repo.TimesheetRepository;
import com.axelor.apps.hr.exception.IExceptionMessage;
import com.axelor.apps.hr.report.IReport;
import com.axelor.apps.hr.service.HRMenuTagService;
import com.axelor.apps.hr.service.MailManagementService;
import com.axelor.apps.hr.service.config.HRConfigService;
import com.axelor.apps.hr.service.expense.ExpenseService;
import com.axelor.apps.message.db.Template;
import com.axelor.auth.AuthUtils;
import com.axelor.auth.db.User;
import com.axelor.db.JPA;
import com.axelor.db.Query;
import com.axelor.exception.AxelorException;
import com.axelor.exception.db.IException;
import com.axelor.exception.service.TraceBackService;
import com.axelor.i18n.I18n;
import com.axelor.inject.Beans;
import com.axelor.meta.schema.actions.ActionView;
import com.axelor.rpc.ActionRequest;
import com.axelor.rpc.ActionResponse;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.persist.Transactional;

public class ExpenseController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Inject
    private HRConfigService hrConfigService;
    @Inject
    private HRMenuTagService hrMenuTagService;
    @Inject
    private MailManagementService mailManagementService;
    @Inject
    private ExpenseService expenseService;
    @Inject
    private GeneralService generalService;

    public void createAnalyticDistributionWithTemplate(ActionRequest request, ActionResponse response)
            throws AxelorException {
        ExpenseLine expenseLine = request.getContext().asType(ExpenseLine.class);
        Expense expense = expenseLine.getExpense();
        if (expense == null) {
            expense = request.getContext().getParentContext().asType(Expense.class);
            expenseLine.setExpense(expense);
        }
        if (expenseLine.getAnalyticDistributionTemplate() != null) {
            expenseLine = expenseService.createAnalyticDistributionWithTemplate(expenseLine);
            response.setValue("analyticDistributionLineList", expenseLine.getAnalyticDistributionLineList());
        } else {
            throw new AxelorException(I18n.get("No template selected"), IException.CONFIGURATION_ERROR);
        }
    }

    public void computeAnalyticDistribution(ActionRequest request, ActionResponse response) throws AxelorException {
        ExpenseLine expenseLine = request.getContext().asType(ExpenseLine.class);
        Expense expense = expenseLine.getExpense();
        if (expense == null) {
            expense = request.getContext().getParentContext().asType(Expense.class);
            expenseLine.setExpense(expense);
        }
        if (Beans.get(GeneralService.class).getGeneral().getManageAnalyticAccounting()) {
            expenseLine = expenseService.computeAnalyticDistribution(expenseLine);
            response.setValue("analyticDistributionLineList", expenseLine.getAnalyticDistributionLineList());
        }
    }

    public void editExpense(ActionRequest request, ActionResponse response) {
        List<Expense> expenseList = Beans.get(ExpenseRepository.class).all()
                .filter("self.user = ?1 AND self.company = ?2 AND self.statusSelect = 1", AuthUtils.getUser(),
                        AuthUtils.getUser().getActiveCompany())
                .fetch();
        if (expenseList.isEmpty()) {
            response.setView(ActionView.define(I18n.get("Expense")).model(Expense.class.getName())
                    .add("form", "expense-form").map());
        } else if (expenseList.size() == 1) {
            response.setView(ActionView.define(I18n.get("Expense")).model(Expense.class.getName())
                    .add("form", "expense-form").param("forceEdit", "true")
                    .context("_showRecord", String.valueOf(expenseList.get(0).getId())).map());
        } else {
            response.setView(ActionView.define(I18n.get("Expense")).model(Wizard.class.getName())
                    .add("form", "popup-expense-form").param("forceEdit", "true").param("popup", "true")
                    .param("show-toolbar", "false").param("show-confirm", "false").param("forceEdit", "true")
                    .param("popup-save", "false").map());
        }
    }

    public void editExpenseSelected(ActionRequest request, ActionResponse response) {
        Map expenseMap = (Map) request.getContext().get("expenseSelect");
        Expense expense = Beans.get(ExpenseRepository.class).find(new Long((Integer) expenseMap.get("id")));
        response.setView(ActionView.define(I18n.get("Expense")).model(Expense.class.getName())
                .add("form", "expense-form").param("forceEdit", "true").domain("self.id = " + expenseMap.get("id"))
                .context("_showRecord", String.valueOf(expense.getId())).map());
    }

    public void validateExpense(ActionRequest request, ActionResponse response) throws AxelorException {

        List<Expense> expenseList = Lists.newArrayList();

        if (AuthUtils.getUser().getEmployee() != null && AuthUtils.getUser().getEmployee().getHrManager()) {
            expenseList = Query.of(Expense.class)
                    .filter("self.company = ?1 AND  self.statusSelect = 2", AuthUtils.getUser().getActiveCompany())
                    .fetch();
        } else {
            expenseList = Query.of(Expense.class)
                    .filter("self.user.employee.manager = ?1 AND self.company = ?2 AND  self.statusSelect = 2",
                            AuthUtils.getUser(), AuthUtils.getUser().getActiveCompany())
                    .fetch();
        }

        List<Long> expenseListId = new ArrayList<Long>();
        for (Expense expense : expenseList) {
            expenseListId.add(expense.getId());
        }
        if (AuthUtils.getUser().getEmployee() != null && AuthUtils.getUser().getEmployee().getManager() == null
                && !AuthUtils.getUser().getEmployee().getHrManager()) {
            expenseList = Query.of(Expense.class)
                    .filter("self.user = ?1 AND self.company = ?2 AND self.statusSelect = 2 ", AuthUtils.getUser(),
                            AuthUtils.getUser().getActiveCompany())
                    .fetch();
        }
        for (Expense expense : expenseList) {
            expenseListId.add(expense.getId());
        }
        String expenseListIdStr = "-2";
        if (!expenseListId.isEmpty()) {
            expenseListIdStr = Joiner.on(",").join(expenseListId);
        }

        response.setView(ActionView.define(I18n.get("Expenses to Validate")).model(Expense.class.getName())
                .add("grid", "expense-validate-grid").add("form", "expense-form")
                .domain("self.id in (" + expenseListIdStr + ")").map());
    }

    public void historicExpense(ActionRequest request, ActionResponse response) {

        List<Expense> expenseList = Lists.newArrayList();

        if (AuthUtils.getUser().getEmployee() != null && AuthUtils.getUser().getEmployee().getHrManager()) {
            expenseList = Query.of(Expense.class)
                    .filter("self.company = ?1 AND (self.statusSelect = 3 OR self.statusSelect = 4)",
                            AuthUtils.getUser().getActiveCompany())
                    .fetch();
        } else {
            expenseList = Query.of(Expense.class).filter(
                    "self.user.employee.manager = ?1 AND self.company = ?2 AND (self.statusSelect = 3 OR self.statusSelect = 4)",
                    AuthUtils.getUser(), AuthUtils.getUser().getActiveCompany()).fetch();
        }

        List<Long> expenseListId = new ArrayList<Long>();
        for (Expense expense : expenseList) {
            expenseListId.add(expense.getId());
        }

        String expenseListIdStr = "-2";
        if (!expenseListId.isEmpty()) {
            expenseListIdStr = Joiner.on(",").join(expenseListId);
        }

        response.setView(ActionView.define(I18n.get("Historic colleague Expenses")).model(Expense.class.getName())
                .add("grid", "expense-grid").add("form", "expense-form")
                .domain("self.id in (" + expenseListIdStr + ")").map());
    }

    public void showSubordinateExpenses(ActionRequest request, ActionResponse response) {
        List<User> userList = Query.of(User.class).filter("self.employee.manager = ?1", AuthUtils.getUser())
                .fetch();
        List<Long> expenseListId = new ArrayList<Long>();
        for (User user : userList) {
            List<Expense> expenseList = Query.of(Expense.class)
                    .filter("self.user.employee.manager = ?1 AND self.company = ?2 AND self.statusSelect = 2", user,
                            AuthUtils.getUser().getActiveCompany())
                    .fetch();
            for (Expense expense : expenseList) {
                expenseListId.add(expense.getId());
            }
        }
        if (expenseListId.isEmpty()) {
            response.setNotify(I18n.get("No expense to be validated by your subordinates"));
        } else {
            String expenseListIdStr = "-2";
            if (!expenseListId.isEmpty()) {
                expenseListIdStr = Joiner.on(",").join(expenseListId);
            }

            response.setView(ActionView.define(I18n.get("Expenses to be Validated by your subordinates"))
                    .model(Expense.class.getName()).add("grid", "expense-grid").add("form", "expense-form")
                    .domain("self.id in (" + expenseListIdStr + ")").map());
        }
    }

    public void compute(ActionRequest request, ActionResponse response) {
        Expense expense = request.getContext().asType(Expense.class);
        expense = expenseService.compute(expense);
        response.setValues(expense);
    }

    public void ventilate(ActionRequest request, ActionResponse response) throws AxelorException {
        Expense expense = request.getContext().asType(Expense.class);
        expense = Beans.get(ExpenseRepository.class).find(expense.getId());
        Move move = expenseService.ventilate(expense);
        response.setReload(true);
        response.setView(ActionView.define(I18n.get("Move")).model(Move.class.getName()).add("grid", "move-grid")
                .add("form", "move-form").context("_showRecord", String.valueOf(move.getId())).map());
    }

    public void cancelExpense(ActionRequest request, ActionResponse response) throws AxelorException {
        Expense expense = request.getContext().asType(Expense.class);
        expense = Beans.get(ExpenseRepository.class).find(expense.getId());
        expenseService.cancel(expense);
        response.setReload(true);
    }

    public void validateDates(ActionRequest request, ActionResponse response) throws AxelorException {
        Expense expense = request.getContext().asType(Expense.class);
        if (expense.getExpenseLineList() != null) {
            List<ExpenseLine> expenseLineList = expense.getExpenseLineList();
            List<Integer> expenseLineId = new ArrayList<Integer>();
            int compt = 0;
            for (ExpenseLine expenseLine : expenseLineList) {
                compt++;
                if (expenseLine.getExpenseDate().isAfter(generalService.getTodayDate())) {
                    expenseLineId.add(compt);
                }
            }
            if (!expenseLineId.isEmpty()) {
                String ids = Joiner.on(",").join(expenseLineId);
                throw new AxelorException(
                        String.format(I18n.get("Problme de date pour la (les) ligne(s) : " + ids)),
                        IException.CONFIGURATION_ERROR);
            }
        }
    }

    public void printExpense(ActionRequest request, ActionResponse response) throws AxelorException {

        Expense expense = request.getContext().asType(Expense.class);

        User user = AuthUtils.getUser();
        String language = user != null
                ? (user.getLanguage() == null || user.getLanguage().equals("")) ? "en" : user.getLanguage()
                : "en";

        String name = I18n.get("Expense") + " " + expense.getFullName().replace("/", "-");

        String fileLink = ReportFactory.createReport(IReport.EXPENSE, name).addParam("ExpenseId", expense.getId())
                .addParam("Locale", language).toAttach(expense).generate().getFileLink();

        logger.debug("Printing " + name);

        response.setView(ActionView.define(name).add("html", fileLink).map());
    }

    /* Count Tags displayed on the menu items */

    public String expenseValidateTag() {
        Expense expense = new Expense();
        return hrMenuTagService.CountRecordsTag(expense);
    }

    public String expenseVentilateTag() {
        Long total = JPA.all(Expense.class).filter("self.statusSelect = 3 AND self.ventilated = false").count();

        return String.format("%s", total);
    }

    //sending expense and sending mail to manager
    public void send(ActionRequest request, ActionResponse response) throws AxelorException {

        try {
            Expense expense = request.getContext().asType(Expense.class);
            if (!hrConfigService.getHRConfig(expense.getUser().getActiveCompany()).getExpenseMailNotification()) {
                response.setValue("statusSelect", TimesheetRepository.STATUS_CONFIRMED);
                response.setValue("sentDate", generalService.getTodayDate());
                response.setView(ActionView.define(I18n.get("Expense")).model(Expense.class.getName())
                        .add("form", "expense-form").map());
            } else {
                User manager = expense.getUser().getEmployee().getManager();
                if (manager != null) {
                    Template template = hrConfigService.getHRConfig(expense.getUser().getActiveCompany())
                            .getSentExpenseTemplate();
                    if (mailManagementService.sendEmail(template, expense.getId())) {
                        String message = "Email sent to";
                        response.setFlash(I18n.get(message) + " " + manager.getFullName());
                        response.setValue("statusSelect", TimesheetRepository.STATUS_CONFIRMED);
                        response.setValue("sentDate", generalService.getTodayDate());
                        response.setView(ActionView.define(I18n.get("Expense")).model(Expense.class.getName())
                                .add("form", "expense-form").map());
                    } else {
                        throw new AxelorException(
                                String.format(I18n.get(IExceptionMessage.HR_CONFIG_TEMPLATES),
                                        expense.getUser().getActiveCompany().getName()),
                                IException.CONFIGURATION_ERROR);
                    }
                }
            }
        } catch (Exception e) {
            TraceBackService.trace(response, e);
        }
    }

    //validating expense and sending mail to applicant
    public void valid(ActionRequest request, ActionResponse response) throws AxelorException {

        try {
            Expense expense = request.getContext().asType(Expense.class);
            if (!hrConfigService.getHRConfig(expense.getUser().getActiveCompany()).getExpenseMailNotification()) {
                response.setValue("statusSelect", TimesheetRepository.STATUS_VALIDATED);
                response.setValue("validatedBy", AuthUtils.getUser());
                response.setValue("validationDate", generalService.getTodayDate());
            } else {
                User manager = expense.getUser().getEmployee().getManager();
                if (manager != null) {
                    Template template = hrConfigService.getHRConfig(expense.getUser().getActiveCompany())
                            .getValidatedExpenseTemplate();
                    if (mailManagementService.sendEmail(template, expense.getId())) {
                        String message = "Email sent to";
                        response.setFlash(I18n.get(message) + " " + expense.getUser().getFullName());
                        response.setValue("statusSelect", TimesheetRepository.STATUS_VALIDATED);
                        response.setValue("validatedBy", AuthUtils.getUser());
                        response.setValue("validationDate", generalService.getTodayDate());
                    } else {
                        throw new AxelorException(
                                String.format(I18n.get(IExceptionMessage.HR_CONFIG_TEMPLATES),
                                        expense.getUser().getActiveCompany().getName()),
                                IException.CONFIGURATION_ERROR);
                    }
                }
            }
        } catch (Exception e) {
            TraceBackService.trace(response, e);
        }
    }

    //refusing expense and sending mail to applicant
    public void refuse(ActionRequest request, ActionResponse response) throws AxelorException {

        try {
            Expense expense = request.getContext().asType(Expense.class);
            if (!hrConfigService.getHRConfig(expense.getUser().getActiveCompany()).getExpenseMailNotification()) {
                response.setValue("statusSelect", TimesheetRepository.STATUS_REFUSED);
                response.setValue("refusedBy", AuthUtils.getUser());
                response.setValue("refusalDate", generalService.getTodayDate());
            } else {
                User manager = expense.getUser().getEmployee().getManager();
                if (manager != null) {
                    Template template = hrConfigService.getHRConfig(expense.getUser().getActiveCompany())
                            .getRefusedExpenseTemplate();
                    if (mailManagementService.sendEmail(template, expense.getId())) {
                        String message = "Email sent to";
                        response.setFlash(I18n.get(message) + " " + expense.getUser().getFullName());
                        response.setValue("statusSelect", TimesheetRepository.STATUS_REFUSED);
                        response.setValue("refusedBy", AuthUtils.getUser());
                        response.setValue("refusalDate", generalService.getTodayDate());
                    } else {
                        throw new AxelorException(
                                String.format(I18n.get(IExceptionMessage.HR_CONFIG_TEMPLATES),
                                        expense.getUser().getActiveCompany().getName()),
                                IException.CONFIGURATION_ERROR);
                    }
                }
            }
        } catch (Exception e) {
            TraceBackService.trace(response, e);
        }
    }

    public void fillKilometricExpenseProduct(ActionRequest request, ActionResponse response)
            throws AxelorException {

        try {
            Expense expense = request.getContext().getParentContext().asType(Expense.class);
            HRConfig hrConfig = hrConfigService.getHRConfig(expense.getCompany());
            Product expenseProduct = hrConfigService.getKilometricExpenseProduct(hrConfig);
            logger.debug("Get Kilometric expense product : {}", expenseProduct);
            response.setValue("expenseProduct", expenseProduct);
        } catch (Exception e) {
            TraceBackService.trace(response, e);
        }
    }

    @Transactional
    public void insertKMExpenses(ActionRequest request, ActionResponse response) {
        User user = AuthUtils.getUser();
        if (user != null) {
            Expense expense = Beans.get(ExpenseRepository.class).all()
                    .filter("self.statusSelect = 1 AND self.user.id = ?1", user.getId()).order("-id").fetchOne();
            if (expense == null) {
                expense = new Expense();
                expense.setUser(user);
                expense.setCompany(user.getActiveCompany());
                expense.setStatusSelect(TimesheetRepository.STATUS_DRAFT);
            }
            ExpenseLine expenseLine = new ExpenseLine();
            expenseLine.setDistance(new BigDecimal(request.getData().get("kmNumber").toString()));
            expenseLine.setFromCity(request.getData().get("locationFrom").toString());
            expenseLine.setToCity(request.getData().get("locationTo").toString());
            expenseLine
                    .setKilometricTypeSelect(new Integer(request.getData().get("allowanceTypeSelect").toString()));
            expenseLine.setComments(request.getData().get("comments").toString());
            expenseLine.setExpenseDate(new LocalDate(request.getData().get("date").toString()));
            if (user.getEmployee() != null && user.getEmployee().getKilometricAllowParam() != null) {
                expenseLine.setKilometricAllowParam(user.getEmployee().getKilometricAllowParam());
                KilometricAllowanceRate kilometricAllowanceRate = Beans.get(KilometricAllowanceRateRepository.class)
                        .findByVehicleKillometricAllowanceParam(user.getEmployee().getKilometricAllowParam());
                if (kilometricAllowanceRate != null) {
                    BigDecimal rate = kilometricAllowanceRate.getRate();
                    if (rate != null) {
                        expenseLine.setTotalAmount(rate.multiply(expenseLine.getDistance()));
                    }
                }
            }

            expense.addExpenseLineListItem(expenseLine);

            Beans.get(ExpenseRepository.class).save(expense);
        }
    }

}