/**
* Copyright © 2002 Instituto Superior Técnico
*
* This file is part of FenixEdu Academic.
*
* FenixEdu Academic is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FenixEdu Academic 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with FenixEdu Academic. If not, see <http://www.gnu.org/licenses/>.
*/
package org.fenixedu.academic.ui.struts.action.manager.payments;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.fenixedu.academic.domain.accounting.PostingRule;
import org.fenixedu.academic.domain.exceptions.DomainException;
import org.fenixedu.academic.domain.phd.PhdProgram;
import org.fenixedu.academic.domain.phd.debts.PhdGratuityPR;
import org.fenixedu.academic.domain.phd.debts.PhdGratuityPaymentPeriod;
import org.fenixedu.academic.domain.phd.debts.PhdGratuityPriceQuirk;
import org.fenixedu.academic.util.Money;
import org.fenixedu.bennu.core.domain.Bennu;
import org.fenixedu.bennu.struts.annotations.Forward;
import org.fenixedu.bennu.struts.annotations.Forwards;
import org.fenixedu.bennu.struts.annotations.Mapping;
import org.joda.time.DateTime;
import org.joda.time.DateTimeFieldType;
import org.joda.time.Interval;
import org.joda.time.Partial;
import pt.ist.fenixWebFramework.renderers.utils.RenderUtils;
import pt.ist.fenixframework.Atomic;
@Mapping(path = "/phdPostingRules", module = "manager",
formBeanClass = PostingRulesManagementDA.PostingRulesManagementForm.class, functionality = PostingRulesManagementDA.class)
@Forwards({
@Forward(name = "showPhdProgramPostingRules",
path = "/manager/payments/postingRules/management/phd/showPhdProgramPostingRules.jsp"),
@Forward(name = "viewPostingRuleDetails",
path = "/manager/payments/postingRules/management/phd/viewPostingRuleDetails.jsp"),
@Forward(name = "editPhdProgramPostingRule",
path = "/manager/payments/postingRules/management/phd/editPhdProgramPostingRule.jsp"),
@Forward(name = "addPhdProgramPostingRule",
path = "/manager/payments/postingRules/management/phd/addPhdProgramPostingRule.jsp") })
public class PhdPostingRulesManagementDA extends PostingRulesManagementDA {
public static final Integer STANDARD_GRATUITY = 3000;
public static final Double STANDARD_FINE_RATE = 0.01;
public static class CreateGratuityPhdPRQuickBean implements Serializable {
Integer year;
Integer gratuity;
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
public Integer getGratuity() {
return gratuity;
}
public void setGratuity(Integer gratuity) {
this.gratuity = gratuity;
}
}
public static class CreateGratuityPhdPRPeriodBean implements Serializable {
Partial periodStartDate;
Partial periodEndDate;
Partial limitePaymentDay;
public Partial getPeriodStartDate() {
return periodStartDate;
}
public void setPeriodStartDate(Partial periodStartDate) {
this.periodStartDate = periodStartDate;
}
public Partial getPeriodEndDate() {
return periodEndDate;
}
public void setPeriodEndDate(Partial periodEndDate) {
this.periodEndDate = periodEndDate;
}
public Partial getLimitePaymentDay() {
return limitePaymentDay;
}
public void setLimitePaymentDay(Partial limitePaymentDay) {
this.limitePaymentDay = limitePaymentDay;
}
public String getPeriodStartString() {
return periodStartDate.toString("d/M");
}
public String getPeriodEndString() {
return periodEndDate.toString("d/M");
}
public String getLimitePaymentDayString() {
return limitePaymentDay.toString("d/M");
}
public DateTime getStartAsDateTime() {
return new DateTime(new DateTime().getYear(), getPeriodStartDate().get(DateTimeFieldType.monthOfYear()),
getPeriodStartDate().get(DateTimeFieldType.dayOfMonth()), 0, 0, 0, 0);
}
public DateTime getEndAsDateTime() {
return new DateTime(new DateTime().getYear(), getPeriodEndDate().get(DateTimeFieldType.monthOfYear()),
getPeriodEndDate().get(DateTimeFieldType.dayOfMonth()), 0, 0, 0, 0);
}
private Interval toInterval() {
DateTime start = getStartAsDateTime();
DateTime end = getEndAsDateTime();
return new Interval(start, end);
}
}
public static class CreateGratuityPhdBean implements Serializable {
DateTime startDate = new DateTime();
DateTime endDate;
Integer gratuity = STANDARD_GRATUITY;
Double fineRate = STANDARD_FINE_RATE;
private List<CreateGratuityPhdPRPeriodBean> periods = new ArrayList<CreateGratuityPhdPRPeriodBean>();
private List<CreateGratuityPhdPRQuickBean> exceptions = new ArrayList<CreateGratuityPhdPRQuickBean>();
public DateTime getStartDate() {
return startDate;
}
public void setStartDate(DateTime startDate) {
this.startDate = startDate;
}
public DateTime getEndDate() {
return endDate;
}
public void setEndDate(DateTime endDate) {
this.endDate = endDate;
}
public Integer getGratuity() {
return gratuity;
}
public void setGratuity(Integer gratuity) {
this.gratuity = gratuity;
}
public Double getFineRate() {
return fineRate;
}
public void setFineRate(Double fineRate) {
this.fineRate = fineRate;
}
public List<CreateGratuityPhdPRPeriodBean> getPeriods() {
return periods;
}
public void setPeriods(List<CreateGratuityPhdPRPeriodBean> periods) {
this.periods = periods;
}
public List<CreateGratuityPhdPRQuickBean> getExceptions() {
return exceptions;
}
public void setExceptions(List<CreateGratuityPhdPRQuickBean> exceptions) {
this.exceptions = exceptions;
}
}
/* Phd Programs */
public ActionForward showPhdProgramPostingRules(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
request.setAttribute("phdProgram", phdProgram);
return mapping.findForward("showPhdProgramPostingRules");
}
@Override
public ActionForward viewPostingRuleDetails(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
request.setAttribute("phdProgram", getDomainObject(request, "phdProgramId"));
request.setAttribute("postingRule", getPostingRule(request));
return mapping.findForward("viewPostingRuleDetails");
}
public ActionForward prepareAddGratuityPhdPostingRule(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
final CreateGratuityPhdPRPeriodBean period = getRenderedObject("period");
final CreateGratuityPhdPRQuickBean quirks = getRenderedObject("quirks");
final CreateGratuityPhdBean bean = getRenderedObject("bean");
request.setAttribute("phdProgram", phdProgram);
request.setAttribute("bean", (bean == null) ? new CreateGratuityPhdBean() : bean);
request.setAttribute("period", (period == null) ? new CreateGratuityPhdPRPeriodBean() : period);
request.setAttribute("quirks", (quirks == null) ? new CreateGratuityPhdPRQuickBean() : quirks);
return mapping.findForward("addPhdProgramPostingRule");
}
public ActionForward addPeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final CreateGratuityPhdPRPeriodBean period = getRenderedObject("period");
final CreateGratuityPhdBean bean = getRenderedObject("bean");
final CreateGratuityPhdPRQuickBean quirks = getRenderedObject("quirks");
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
if (period.periodEndDate == null || period.periodStartDate == null || period.limitePaymentDay == null) {
addErrorMessage(request, "bean", "error.missing.field.in.period.form");
return prepareAddGratuityPhdPostingRule(mapping, form, request, response);
}
Interval created = period.toInterval();
if (period.getStartAsDateTime().isAfter(period.getEndAsDateTime())) {
addErrorMessage(request, "bean", "error.end.before.start");
return backToAddPeriod(mapping, request, period, bean, phdProgram, quirks);
}
for (CreateGratuityPhdPRPeriodBean previousPeriod : bean.getPeriods()) {
if (previousPeriod.toInterval().overlap(created) != null) {
addErrorMessage(request, "bean", "error.intervals.overlap");
return backToAddPeriod(mapping, request, period, bean, phdProgram, quirks);
}
}
bean.getPeriods().add(period);
RenderUtils.invalidateViewState("phdProgram");
request.setAttribute("phdProgram", phdProgram);
RenderUtils.invalidateViewState("bean");
request.setAttribute("bean", bean);
RenderUtils.invalidateViewState("period");
request.setAttribute("period", new CreateGratuityPhdPRPeriodBean());
return mapping.findForward("addPhdProgramPostingRule");
}
public ActionForward removePeriod(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final CreateGratuityPhdBean bean = getRenderedObject("bean");
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
final int index = Integer.parseInt(request.getParameter("periodToRemove"));
bean.periods.remove(index);
request.setAttribute("phdProgram", phdProgram);
request.setAttribute("bean", bean);
request.setAttribute("period", new CreateGratuityPhdPRPeriodBean());
return mapping.findForward("addPhdProgramPostingRule");
}
public ActionForward addQuirk(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
final CreateGratuityPhdPRPeriodBean period = getRenderedObject("period");
final CreateGratuityPhdPRQuickBean quirks = getRenderedObject("quirks");
final CreateGratuityPhdBean bean = getRenderedObject("bean");
bean.getExceptions().add(quirks);
return backToAddPeriod(mapping, request, period, bean, phdProgram, new CreateGratuityPhdPRQuickBean());
}
public ActionForward removeQuirk(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
final CreateGratuityPhdPRPeriodBean period = getRenderedObject("period");
final CreateGratuityPhdPRQuickBean quirks = getRenderedObject("quirks");
final CreateGratuityPhdBean bean = getRenderedObject("bean");
final int index = Integer.parseInt(request.getParameter("quirkToRemove"));
bean.getExceptions().remove(index);
return backToAddPeriod(mapping, request, period, bean, phdProgram, quirks);
}
private ActionForward backToAddPeriod(ActionMapping mapping, HttpServletRequest request,
final CreateGratuityPhdPRPeriodBean period, final CreateGratuityPhdBean bean, final PhdProgram phdProgram,
Object quirks) {
RenderUtils.invalidateViewState("phdProgram");
request.setAttribute("phdProgram", phdProgram);
RenderUtils.invalidateViewState("bean");
request.setAttribute("bean", bean);
RenderUtils.invalidateViewState("period");
request.setAttribute("period", period);
RenderUtils.invalidateViewState("quirks");
request.setAttribute("quirks", quirks);
return mapping.findForward("addPhdProgramPostingRule");
}
@Atomic
private void makeGratuityPostingRule(CreateGratuityPhdBean bean, PhdProgram phdProgram) {
if (bean.getPeriods().size() == 0) {
throw new RuntimeException("error.empty.periods");
}
PhdGratuityPR postingRule =
new PhdGratuityPR(bean.getStartDate(), bean.getEndDate(), phdProgram.getServiceAgreementTemplate(), new Money(
bean.getGratuity()), bean.getFineRate());
for (CreateGratuityPhdPRPeriodBean periodBean : bean.getPeriods()) {
PhdGratuityPaymentPeriod period =
new PhdGratuityPaymentPeriod(periodBean.getPeriodStartDate(), periodBean.getPeriodEndDate(),
periodBean.getLimitePaymentDay());
postingRule.addPhdGratuityPaymentPeriods(period);
period.setRootDomainObject(Bennu.getInstance());
}
for (CreateGratuityPhdPRQuickBean quirkBean : bean.getExceptions()) {
PhdGratuityPriceQuirk quirk = new PhdGratuityPriceQuirk(quirkBean.getYear(), new Money(quirkBean.getGratuity()));
postingRule.addPhdGratuityPriceQuirks(quirk);
quirk.setRootDomainObject(Bennu.getInstance());
}
postingRule.setRootDomainObject(Bennu.getInstance());
}
public ActionForward addGratuityPhdPostingRule(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final PhdProgram phdProgram = getDomainObject(request, "phdProgramId");
CreateGratuityPhdBean bean = (CreateGratuityPhdBean) getRenderedObject("bean");
try {
makeGratuityPostingRule(bean, phdProgram);
} catch (DomainException e) {
addErrorMessage(request, "bean", e.getMessage());
return prepareAddGratuityPhdPostingRule(mapping, form, request, response);
} catch (RuntimeException e) {
addErrorMessage(request, "bean", e.getMessage());
return prepareAddGratuityPhdPostingRule(mapping, form, request, response);
}
return showPhdProgramPostingRules(mapping, form, request, response);
}
@Override
protected PostingRule getPostingRule(HttpServletRequest request) {
return getDomainObject(request, "postingRuleId");
}
public ActionForward prepareEditPhdProgramPostingRule(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
final PostingRule postingRule = getPostingRule(request);
request.setAttribute("phdProgram", getDomainObject(request, "phdProgramId"));
request.setAttribute("postingRule", postingRule);
return mapping.findForward("editPhdProgramPostingRule");
}
public ActionForward editPhdProgramPostingRuleInvalid(ActionMapping mapping, ActionForm form, HttpServletRequest request,
HttpServletResponse response) {
request.setAttribute("phdProgram", getDomainObject(request, "phdProgramId"));
request.setAttribute("postingRule", getRenderedObject("postingRule"));
return mapping.findForward("editPhdProgramPostingRule");
}
}