/** * 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.residenceManagement; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFRow; import org.apache.poi.hssf.usermodel.HSSFSheet; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.fenixedu.academic.domain.accounting.ResidenceEvent; import org.fenixedu.academic.domain.organizationalStructure.ResidenceManagementUnit; import org.fenixedu.academic.domain.residence.ResidenceMonth; import org.fenixedu.academic.dto.residenceManagement.ImportResidenceEventBean; import org.fenixedu.academic.dto.residenceManagement.ResidenceDebtEventBean; import org.fenixedu.academic.dto.residenceManagement.ResidenceEventBean; import org.fenixedu.academic.dto.residenceManagement.ResidentListsHolderBean; import org.fenixedu.academic.service.services.residenceManagement.CreateResidenceEvents; import org.fenixedu.academic.service.services.residenceManagement.PayResidenceEvent; import org.fenixedu.academic.ui.struts.action.base.FenixDispatchAction; 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 pt.ist.fenixWebFramework.renderers.utils.RenderUtils; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.FenixFramework; @Mapping(path = "/residenceManagement", module = "residenceManagement", functionality = ResidenceEventManagementDispatchAction.class) @Forwards({ @Forward(name = "importData", path = "/residenceManagement/importData.jsp"), @Forward(name = "yearConfiguration", path = "residenceManagement-yearConfiguration"), @Forward(name = "editPaymentLimitDay", path = "/residenceManagement/editPaymentLimitDay.jsp"), @Forward(name = "importCurrentDebt", path = "/residenceManagement/importCurrentDebts.jsp"), @Forward(name = "editRoomValues", path = "/residenceManagement/editRoomValues.jsp"), @Forward(name = "missingPayments", path = "/residenceManagement/missingPayment.jsp") }) public class ResidenceManagementDispatchAction extends FenixDispatchAction { public ActionForward missingPayments(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { List<ResidenceEvent> results = new ArrayList<ResidenceEvent>(); for (ResidenceMonth month : rootDomainObject.getResidenceMonths0Set()) { for (ResidenceEvent residenceEvent : month.getEventsSet()) { if (residenceEvent.isInDebt()) { results.add(residenceEvent); } } } Collections.sort(results, new Comparator<ResidenceEvent>() { @Override public int compare(ResidenceEvent o1, ResidenceEvent o2) { return o1.getEventStateDate().compareTo(o2.getEventStateDate()); } }); request.setAttribute("list", results); return mapping.findForward("missingPayments"); } public ActionForward importCurrentDebts(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { ImportResidenceEventBean bean = getRenderedObject("importFile"); if (bean == null) { ResidenceMonth month = getResidenceMonth(request); bean = month != null ? new ImportResidenceEventBean(month) : new ImportResidenceEventBean(); } else { List<ResidenceEventBean> sucessful = new ArrayList<ResidenceEventBean>(); List<ResidenceEventBean> unsucessful = new ArrayList<ResidenceEventBean>(); List<ResidenceEventBean> process = null; try { process = processCurrentDebts(bean); } catch (InvalidSpreadSheetName exception) { addActionMessage(request, "label.error.invalid.spreadsheetname", exception.getRequestedSheet()); request.setAttribute("availableSpreadsheets", exception.getAvailableSpreadSheets()); RenderUtils.invalidateViewState(); request.setAttribute("importFileBean", bean); return mapping.findForward("importCurrentDebt"); } catch (Exception exception) { addActionMessage(request, "label.error.invalid.table"); RenderUtils.invalidateViewState(); request.setAttribute("importFileBean", bean); return mapping.findForward("importCurrentDebt"); } for (ResidenceEventBean eventBean : process) { if (eventBean.getStatus()) { sucessful.add(eventBean); } else { unsucessful.add(eventBean); } } ResidentListsHolderBean listHolder = new ResidentListsHolderBean(sucessful, unsucessful); request.setAttribute("importList", listHolder); } RenderUtils.invalidateViewState(); request.setAttribute("importFileBean", bean); return mapping.findForward("importCurrentDebt"); } public ActionForward importData(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { ImportResidenceEventBean bean = getRenderedObject("importFile"); if (bean == null) { ResidenceMonth month = getResidenceMonth(request); bean = month != null ? new ImportResidenceEventBean(month) : new ImportResidenceEventBean(); } else { List<ResidenceEventBean> sucessful = new ArrayList<ResidenceEventBean>(); List<ResidenceEventBean> unsucessful = new ArrayList<ResidenceEventBean>(); List<ResidenceEventBean> process = null; try { process = process(bean); } catch (InvalidSpreadSheetName exception) { addActionMessage(request, "label.error.invalid.spreadsheetname", exception.getRequestedSheet()); request.setAttribute("availableSpreadsheets", exception.getAvailableSpreadSheets()); RenderUtils.invalidateViewState(); request.setAttribute("importFileBean", bean); return mapping.findForward("importData"); } catch (Exception exception) { addActionMessage(request, "label.error.invalid.table"); RenderUtils.invalidateViewState(); request.setAttribute("importFileBean", bean); return mapping.findForward("importCurrentDebt"); } for (ResidenceEventBean eventBean : process) { if (eventBean.getStatus()) { sucessful.add(eventBean); } else { unsucessful.add(eventBean); } } ResidentListsHolderBean listHolder = new ResidentListsHolderBean(sucessful, unsucessful); request.setAttribute("importList", listHolder); } RenderUtils.invalidateViewState(); request.setAttribute("importFileBean", bean); return mapping.findForward("importData"); } public ActionForward invalid(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { ImportResidenceEventBean bean = getRenderedObject("importFile"); request.setAttribute("importFileBean", bean); return mapping.findForward("importData"); } public ActionForward editPaymentLimitDay(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { return editResidencePriceTableProperty(mapping, actionForm, request, response, "editPaymentLimitDay"); } public ActionForward editRoomValues(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { return editResidencePriceTableProperty(mapping, actionForm, request, response, "editRoomValues"); } private ActionForward editResidencePriceTableProperty(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response, String forwardName) throws Exception { ResidenceManagementUnit unit = getManagementUnit(request); ResidenceMonth month = getResidenceMonth(request); request.setAttribute("residenceMonth", month); request.setAttribute("priceTable", unit.getResidencePriceTable()); return mapping.findForward(forwardName); } private ResidenceManagementUnit getManagementUnit(HttpServletRequest request) { return Bennu.getInstance().getResidenceManagementUnit(); } private ResidenceMonth getResidenceMonth(HttpServletRequest request) { String oid = request.getParameter("monthOID"); return oid == null ? null : FenixFramework.<ResidenceMonth> getDomainObject(oid); } public ActionForward generateDebts(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { ResidentListsHolderBean listHolder = getRenderedObject("importList"); ImportResidenceEventBean eventBean = getRenderedObject("dateBean"); try { CreateResidenceEvents.run(listHolder.getSuccessfulEvents(), eventBean.getResidenceMonth()); } catch (Exception e) { addActionMessage(request, e.getMessage()); return importData(mapping, actionForm, request, response); } request.setAttribute("createdDebts", true); return importData(mapping, actionForm, request, response); } @Atomic public void makePayments(List<ResidenceEventBean> events, HttpServletRequest request) throws Exception { for (ResidenceEventBean event : events) { ResidenceDebtEventBean debtEvent = (ResidenceDebtEventBean) event; PayResidenceEvent.run(getLoggedPerson(request).getUser(), debtEvent.getEventObject(), debtEvent.getPaidDateObject()); } } public ActionForward generatePayments(ActionMapping mapping, ActionForm actionForm, HttpServletRequest request, HttpServletResponse response) throws Exception { ResidentListsHolderBean listHolder = getRenderedObject("importList"); ImportResidenceEventBean eventBean = getRenderedObject("dateBean"); try { makePayments(listHolder.getSuccessfulEvents(), request); } catch (Exception e) { addActionMessage(request, e.getMessage()); return importData(mapping, actionForm, request, response); } request.setAttribute("createdDebts", true); return importCurrentDebts(mapping, actionForm, request, response); } private List<ResidenceEventBean> process(ImportResidenceEventBean bean) throws IOException, InvalidSpreadSheetName { List<ResidenceEventBean> beans = new ArrayList<ResidenceEventBean>(); POIFSFileSystem fs = new POIFSFileSystem(bean.getFile()); HSSFWorkbook wb = new HSSFWorkbook(fs); HSSFSheet sheet = wb.getSheetAt(0); if (sheet == null) { throw new InvalidSpreadSheetName(bean.getSpreadsheetName(), getAllSpreadsheets(wb)); } int i = 2; HSSFRow row; while ((row = sheet.getRow(i)) != null) { String room = row.getCell((short) 0).getStringCellValue(); if (StringUtils.isEmpty(room)) { break; } String userName = getValueFromColumnMayBeNull(row, 1); String fiscalNumber = getValueFromColumnMayBeNull(row, 2); String name = getValueFromColumnMayBeNull(row, 3); Double roomValue = new Double(row.getCell((short) 4).getNumericCellValue()); beans.add(new ResidenceEventBean(userName, fiscalNumber, name, roomValue, room)); i++; } return beans; } private List<ResidenceEventBean> processCurrentDebts(ImportResidenceEventBean bean) throws IOException, InvalidSpreadSheetName { List<ResidenceEventBean> beans = new ArrayList<ResidenceEventBean>(); POIFSFileSystem fs = new POIFSFileSystem(bean.getFile()); HSSFWorkbook wb = new HSSFWorkbook(fs); HSSFSheet sheet = wb.getSheetAt(0); if (sheet == null) { throw new InvalidSpreadSheetName(bean.getSpreadsheetName(), getAllSpreadsheets(wb)); } int i = 2; HSSFRow row; while ((row = sheet.getRow(i)) != null) { String room = row.getCell((short) 0).getStringCellValue(); if (StringUtils.isEmpty(room)) { break; } String userName = getValueFromColumnMayBeNull(row, 1); String fiscalNumber = getValueFromColumnMayBeNull(row, 2); String name = getValueFromColumnMayBeNull(row, 3); Double roomValue = new Double(row.getCell((short) 4).getNumericCellValue()); String paidDate = getDateFromColumn(row, 5); Double roomValuePaid = new Double(row.getCell((short) 6).getNumericCellValue()); ResidenceDebtEventBean residenceDebtEventBean = new ResidenceDebtEventBean(userName, fiscalNumber, name, roomValue, room, paidDate, roomValuePaid); residenceDebtEventBean.setMonth(bean.getResidenceMonth()); beans.add(residenceDebtEventBean); i++; } return beans; } private String getValueFromColumnMayBeNull(HSSFRow row, int i) { HSSFCell cell = row.getCell((short) i); if (cell == null) { return StringUtils.EMPTY; } return getValueFromColumn(row, i); } private String[] getAllSpreadsheets(HSSFWorkbook wb) { String[] spreadsheets = new String[wb.getNumberOfSheets()]; for (int i = 0; i < wb.getNumberOfSheets(); i++) { spreadsheets[i] = wb.getSheetName(i); } return spreadsheets; } private String getDateFromColumn(HSSFRow row, int i) { try { return new SimpleDateFormat("dd-MM-yy").format(row.getCell((short) i).getDateCellValue()); } catch (Exception e) { return row.getCell((short) i).getStringCellValue(); } } private String getValueFromColumn(HSSFRow row, int i) { try { return new Integer(new Double(row.getCell((short) i).getNumericCellValue()).intValue()).toString(); } catch (NumberFormatException e) { return row.getCell((short) i).getStringCellValue(); } catch (IllegalStateException e) { return row.getCell((short) i).getStringCellValue(); } } private static class InvalidSpreadSheetName extends Exception { private final String requestedSheet; private final String[] availableSpreadSheets; public InvalidSpreadSheetName(String requestedSheet, String[] availableSpreadSheets) { this.requestedSheet = requestedSheet; this.availableSpreadSheets = availableSpreadSheets; } public String[] getAvailableSpreadSheets() { return availableSpreadSheets; } public String getRequestedSheet() { return requestedSheet; } } }